"use client";

import { useEffect, useMemo, useRef, useState, type ChangeEvent } from "react";

import Alert from "@mui/material/Alert";
import Avatar from "@mui/material/Avatar";
import Box from "@mui/material/Box";
import Dialog from "@mui/material/Dialog";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import BusinessIcon from "@mui/icons-material/Business";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";

import {
  AppButton,
  AppCancelButton,
  AppSecondaryButton,
} from "@/components/ui/button";
import {
  AppFormField,
  AppFormGrid,
  AppFormTextField,
  getFormBorderColor,
} from "@/components/ui/form";
import { AppSelect } from "@/components/ui/select";
import {
  type Stakeholder,
  type StakeholderFormPayload,
  type StakeholderType,
} from "@/features/stakeholder/stakeholder-data";

const statusOptions = [
  { label: "Active", value: "active" },
  { label: "Inactive", value: "inactive" },
];

type StakeholderFormDialogProps = {
  open: boolean;
  mode: "create" | "edit";
  stakeholder: Stakeholder | null;
  stakeholderTypes: StakeholderType[];
  stakeholders: Stakeholder[];
  isLoadingTypes: boolean;
  isLoadingStakeholders?: boolean;
  isSaving: boolean;
  onClose: () => void;
  onSubmit: (payload: StakeholderFormPayload) => Promise<boolean>;
};

type StakeholderFormState = {
  name: string;
  stakeholderTypeId: string;
  relatedStakeholderId: string;
  existingLogo: string;
  logoFile: File | null;
  description: string;
  active: boolean;
};

const LOGO_MAX_BYTES = 5 * 1024 * 1024;
const LOGO_ACCEPTED_MIME =
    "image/png,image/jpeg,image/jpg,image/webp,image/svg+xml";
const LOGO_ACCEPTED_PREFIX = "image/";
const API_URL =
    process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001/api/v1";

function resolveLogoSrc(value: string | null | undefined) {
  if (!value) {
    return undefined;
  }

  if (value.startsWith("/uploads/")) {
    const backendUrl = API_URL.replace(/\/api(?:\/v\d+)?\/?$/, "");

    return `${backendUrl}${value}`;
  }

  return value;
}

function getInitialForm(stakeholder: Stakeholder | null): StakeholderFormState {
  return {
    name: stakeholder?.name ?? "",
    stakeholderTypeId: stakeholder?.stakeholderTypeId
        ? String(stakeholder.stakeholderTypeId)
        : "",
    relatedStakeholderId: stakeholder?.relatedStakeholderId
        ? String(stakeholder.relatedStakeholderId)
        : "",
    existingLogo: stakeholder?.logo ?? "",
    logoFile: null,
    description: stakeholder?.description ?? "",
    active: stakeholder?.active ?? true,
  };
}

export function StakeholderFormDialog({
                                        open,
                                        mode,
                                        stakeholder,
                                        stakeholderTypes,
                                        stakeholders,
                                        isLoadingTypes,
                                        isLoadingStakeholders = false,
                                        isSaving,
                                        onClose,
                                        onSubmit,
                                      }: StakeholderFormDialogProps) {
  const theme = useTheme();

  const [form, setForm] = useState<StakeholderFormState>(() =>
      getInitialForm(stakeholder),
  );
  const [formError, setFormError] = useState("");

  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const filePreviewUrl = useMemo(() => {
    if (!form.logoFile) {
      return null;
    }

    return URL.createObjectURL(form.logoFile);
  }, [form.logoFile]);

  useEffect(() => {
    if (!filePreviewUrl) {
      return;
    }

    return () => {
      URL.revokeObjectURL(filePreviewUrl);
    };
  }, [filePreviewUrl]);

  const title = mode === "create" ? "Add Stakeholder" : "Edit Stakeholder";
  const submitLabel = mode === "create" ? "Save" : "Save Changes";

  const borderColor = getFormBorderColor(theme);
  const isDark = theme.palette.mode === "dark";

  const stakeholderTypeOptions = stakeholderTypes.map((stakeholderType) => ({
    label: stakeholderType.name,
    value: String(stakeholderType.id),
  }));

  const relatedStakeholderOptions = [
    {
      label: "No related stakeholder",
      value: "",
    },
    ...stakeholders
        .filter((item) => item.id !== stakeholder?.id)
        .map((item) => ({
          label: item.name,
          value: String(item.id),
        })),
  ];

  const previewSrc = filePreviewUrl ?? resolveLogoSrc(form.existingLogo);
  const hasSomeLogo = Boolean(previewSrc);

  const handleTextChange =
      (field: "name" | "description") =>
          (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
            setForm((current) => ({
              ...current,
              [field]: event.target.value,
            }));

            setFormError("");
          };

  const handleTypeChange = (value: string) => {
    setForm((current) => ({
      ...current,
      stakeholderTypeId: value,
    }));

    setFormError("");
  };

  const handleRelatedStakeholderChange = (value: string) => {
    setForm((current) => ({
      ...current,
      relatedStakeholderId: value,
    }));

    setFormError("");
  };

  const handleStatusChange = (value: string) => {
    setForm((current) => ({
      ...current,
      active: value === "active",
    }));

    setFormError("");
  };

  const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0] ?? null;

    event.target.value = "";

    if (!file) {
      return;
    }

    if (!file.type.startsWith(LOGO_ACCEPTED_PREFIX)) {
      setFormError("Logo must be an image (PNG, JPG, WEBP, or SVG).");
      return;
    }

    if (file.size > LOGO_MAX_BYTES) {
      setFormError("Logo file must be 5 MB or smaller.");
      return;
    }

    setForm((current) => ({
      ...current,
      logoFile: file,
    }));

    setFormError("");
  };

  const handleSubmit = async () => {
    const name = form.name.trim();
    const stakeholderTypeId = Number(form.stakeholderTypeId);
    const relatedStakeholderId = form.relatedStakeholderId
        ? Number(form.relatedStakeholderId)
        : null;
    const description = form.description.trim();

    if (!name) {
      setFormError("Please enter stakeholder name.");
      return;
    }

    if (!Number.isInteger(stakeholderTypeId) || stakeholderTypeId < 1) {
      setFormError("Please select stakeholder type.");
      return;
    }

    if (
        relatedStakeholderId !== null &&
        (!Number.isInteger(relatedStakeholderId) || relatedStakeholderId < 1)
    ) {
      setFormError("Please select a valid related stakeholder.");
      return;
    }

    if (
        relatedStakeholderId !== null &&
        relatedStakeholderId === stakeholder?.id
    ) {
      setFormError("Stakeholder cannot be related to itself.");
      return;
    }

    const saved = await onSubmit({
      name,
      stakeholderTypeId,
      relatedStakeholderId,
      ...(form.logoFile ? { logoFile: form.logoFile } : {}),
      ...(description ? { description } : {}),
      active: form.active,
    });

    if (saved) {
      onClose();
    }
  };

  return (
      <Dialog
          open={open}
          onClose={isSaving ? undefined : onClose}
          maxWidth={false}
          scroll="paper"
          sx={{
            "& .MuiBackdrop-root": {
              backgroundColor:
                  theme.palette.mode === "dark"
                      ? alpha("#000000", 0.72)
                      : "rgba(0, 0, 0, 0.48)",
            },
            "& .MuiDialog-container": {
              justifyContent: "flex-end",
              alignItems: "flex-start",
            },
          }}
          slotProps={{
            paper: {
              sx: {
                mt: 0,
                mr: 0,
                width: { xs: "100vw", md: 720, xl: 820 },
                maxWidth: "calc(100vw - 16px)",
                height: "auto",
                maxHeight: "calc(100vh - 16px)",
                borderRadius: "10px",
                overflow: "hidden",
                bgcolor: theme.palette.background.paper,
                color: theme.palette.text.primary,
              },
            },
          }}
      >
        <Box
            sx={{
              px: 2.5,
              py: 2,
              borderBottom: `1px solid ${borderColor}`,
            }}
        >
          <Typography sx={{ fontSize: 20, fontWeight: 800 }}>
            {title}
          </Typography>
        </Box>

        <Box
            sx={{
              px: 2.5,
              py: 2.5,
              maxHeight: "calc(100vh - 152px)",
              overflowY: "auto",
            }}
        >
          <AppFormGrid columns={2} sx={{ gap: 2.4 }}>
            <AppFormField label="Stakeholder Name" required>
              <AppFormTextField
                  value={form.name}
                  onChange={handleTextChange("name")}
                  placeholder="Ministry of Commerce"
                  disabled={isSaving}
              />
            </AppFormField>

            <AppFormField label="Stakeholder Type" required>
              <AppSelect
                  value={form.stakeholderTypeId}
                  onChange={handleTypeChange}
                  options={stakeholderTypeOptions}
                  placeholder={
                    isLoadingTypes ? "Loading stakeholder types" : "Select type"
                  }
                  disabled={isLoadingTypes || isSaving}
              />
            </AppFormField>

            <AppFormField
                label="Related Stakeholder"
                sx={{ gridColumn: { xs: "auto", sm: "1 / -1" } }}
            >
              <AppSelect
                  value={form.relatedStakeholderId}
                  onChange={handleRelatedStakeholderChange}
                  options={relatedStakeholderOptions}
                  placeholder={
                    isLoadingStakeholders
                        ? "Loading stakeholders"
                        : "Select related stakeholder"
                  }
                  disabled={isLoadingStakeholders || isSaving}
              />
            </AppFormField>

            <AppFormField
                label="Logo"
                sx={{ gridColumn: { xs: "auto", sm: "1 / -1" } }}
            >
              <Box
                  sx={{
                    display: "flex",
                    alignItems: "center",
                    gap: 1.5,
                    p: 1.5,
                    borderRadius: "10px",
                    border: `1px dashed ${borderColor}`,
                    bgcolor: isDark ? alpha("#ffffff", 0.04) : "#fafafa",
                  }}
              >
                <Avatar
                    src={previewSrc}
                    variant="rounded"
                    sx={{
                      width: 64,
                      height: 64,
                      bgcolor: isDark ? alpha("#ffffff", 0.08) : "#f5f7fa",
                      color: isDark ? alpha("#ffffff", 0.72) : "#1a64a8",
                    }}
                >
                  {hasSomeLogo ? null : <BusinessIcon sx={{ fontSize: 28 }} />}
                </Avatar>

                <Box sx={{ minWidth: 0, flex: 1 }}>
                  <Typography sx={{ fontSize: 14, fontWeight: 700 }}>
                    Stakeholder Logo
                  </Typography>

                  <Typography
                      sx={{ mt: 0.25, fontSize: 12, color: "text.secondary" }}
                  >
                    PNG, JPG, WEBP, or SVG · up to 5 MB
                    {form.logoFile ? ` · ${form.logoFile.name}` : ""}
                  </Typography>
                </Box>

                <AppSecondaryButton
                    component="label"
                    disabled={isSaving}
                    startIcon={<CloudUploadIcon sx={{ fontSize: 18 }} />}
                    sx={{
                      flexShrink: 0,
                      minWidth: "auto",
                      height: 38,
                      borderRadius: "10px",
                      fontSize: 13,
                      fontWeight: 700,
                    }}
                >
                  {hasSomeLogo ? "Change" : "Upload"}

                  <input
                      ref={fileInputRef}
                      hidden
                      type="file"
                      accept={LOGO_ACCEPTED_MIME}
                      onChange={handleFileChange}
                  />
                </AppSecondaryButton>
              </Box>
            </AppFormField>

            <AppFormField
                label="Description"
                sx={{ gridColumn: { xs: "auto", sm: "1 / -1" } }}
            >
              <AppFormTextField
                  value={form.description}
                  onChange={handleTextChange("description")}
                  placeholder="Write stakeholder description"
                  multiline
                  minRows={6}
                  disabled={isSaving}
                  sx={{
                    "& .MuiOutlinedInput-root": {
                      height: "auto",
                      minHeight: 132,
                      alignItems: "flex-start",
                    },
                  }}
              />
            </AppFormField>

            <AppFormField label="Status">
              <AppSelect
                  value={form.active ? "active" : "inactive"}
                  onChange={handleStatusChange}
                  options={statusOptions}
                  placeholder="Select status"
                  disabled={isSaving}
              />
            </AppFormField>

            {formError ? (
                <Box sx={{ gridColumn: { xs: "auto", sm: "1 / -1" } }}>
                  <Alert severity="error">{formError}</Alert>
                </Box>
            ) : null}
          </AppFormGrid>
        </Box>

        <Box
            sx={{
              px: 2.5,
              py: 1.7,
              borderTop: `1px solid ${borderColor}`,
              display: "flex",
              justifyContent: "flex-end",
              gap: 2,
              bgcolor: theme.palette.background.paper,
            }}
        >
          <AppCancelButton
              onClick={onClose}
              disabled={isSaving}
              sx={{
                width: 140,
              }}
          >
            Cancel
          </AppCancelButton>

          <AppButton
              onClick={handleSubmit}
              disabled={isSaving}
              sx={{
                width: 150,
              }}
          >
            {isSaving ? "Saving..." : submitLabel}
          </AppButton>
        </Box>
      </Dialog>
  );
}
