"use client";

import {
  useRef,
  useState,
  type ChangeEvent,
  type DragEvent,
  type ReactNode,
} from "react";

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 { AppButton, AppCancelButton } from "@/components/ui/button";
import { DocumentFileAttachment } from "@/components/ui/document-file-name";
import {
  AccountCircleIcon,
  CategoryOfIssuesIcon,
  HyperlinkIcon,
  SubmitDateIcon,
} from "@/components/ui/icon";
import { AdditionalAgencyFields } from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/additional-agency-fields";
import {
  getBorderColor,
  getElevatedSelectMenuProps,
} from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/add-dashboard-issue-dialog-styles";
import type {
  Agency,
  UploadStatus,
} from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/add-dashboard-issue-dialog-types";
import { EditorBox } from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/editor-box";
import { IssuesReferenceUploadField } from "@/features/ministry/meeting-summary/components/create-meeting-summary/issues-reference-upload-field";
import {
  agencyDisplayNameToSelectId,
  agencySelectIdToDisplayName,
  agencySelectIdToLogo,
  buildMeetingSummaryIssueAgencies,
} from "@/features/ministry/meeting-summary/components/create-meeting-summary/meeting-summary-issue-agencies";

import { IssueEscalationSelect } from "@/features/ministry/meeting-summary/components/create-meeting-summary/issue-escalation-select";
import {
  IssueStatusSelect,
  getInitialIssueStatus,
} from "@/features/ministry/meeting-summary/components/create-meeting-summary/issue-status-select";
import type { ViewMeetingSummaryIssueRow } from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-data";
import {
  getDisplayFileName,
  isDocumentPlaceholder,
} from "@/lib/document-file";

const DIALOG_Z_INDEX = 1700;
const SELECT_MENU_Z_INDEX = DIALOG_Z_INDEX + 100;

export type UpdateMeetingSummaryIssueSavePayload = {
  issue: ViewMeetingSummaryIssueRow;
  attachment: File | null;
};

type Props = {
  open: boolean;
  issue: ViewMeetingSummaryIssueRow | null;
  submittedBy?: string;
  submittedDate?: string;
  issueDocument?: string;
  issueDocumentSize?: string;
  onClose: () => void;
  onSave?: (payload: UpdateMeetingSummaryIssueSavePayload) => void | Promise<void>;
  saveError?: string | null;
  agencyOptions?: Agency[];
};

function SectionTitle({ children }: { children: ReactNode }) {
  return (
    <Typography
      sx={{
        fontSize: 16,
        fontWeight: 700,
        color: "#414651",
        mb: 2,
      }}
    >
      {children}
    </Typography>
  );
}

function DetailItem({
  icon,
  label,
  children,
}: {
  icon: ReactNode;
  label: string;
  children: ReactNode;
}) {
  return (
    <Box
      sx={{
        display: "flex",
        alignItems: "center",
        gap: { xs: 1.25, md: 3 },
        minWidth: 0,
        minHeight: 27,
      }}
    >
      <Box
        sx={{
          display: "flex",
          alignItems: "center",
          gap: "11px",
          flexShrink: 0,
        }}
      >
        <Box
          sx={{
            color: "#717680",
            display: "flex",
            flexShrink: 0,
            width: 20,
            height: 20,
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          {icon}
        </Box>
        <Typography
          sx={{
            fontSize: 13,
            fontWeight: 400,
            lineHeight: "22px",
            color: "#717680",
            whiteSpace: "nowrap",
          }}
        >
          {label} :
        </Typography>
      </Box>
      <Box
        sx={{
          minWidth: 0,
          display: "flex",
          alignItems: "center",
        }}
      >
        {children}
      </Box>
    </Box>
  );
}

function getEditableFieldValue(value: string) {
  return value === "Not Uploaded" ? "" : value;
}

function isSolvedStatus(status: string) {
  return status.trim().toLowerCase() === "solved";
}

function getExistingIssueReference(issueReference: string) {
  if (isDocumentPlaceholder(issueReference)) {
    return null;
  }

  return {
    name: getDisplayFileName(issueReference, "Issues Reference Document"),
  };
}

type DialogContentProps = {
  issue: ViewMeetingSummaryIssueRow;
  submittedBy: string;
  submittedDate: string;
  issueDocument: string;
  issueDocumentSize: string;
  onClose: () => void;
  onSave?: (payload: UpdateMeetingSummaryIssueSavePayload) => void | Promise<void>;
  saveError?: string | null;
  agencyOptions?: Agency[];
};

function UpdateMeetingSummaryIssueDialogContent({
  issue,
  submittedBy,
  submittedDate,
  issueDocument,
  issueDocumentSize,
  onClose,
  onSave,
  saveError,
  agencyOptions: providedAgencyOptions,
}: DialogContentProps) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [saving, setSaving] = useState(false);
  // Prefer the real government agencies (with real stakeholder ids); fall back
  // to whatever the issue already carries when they have not loaded yet.
  const agencyOptions =
    providedAgencyOptions && providedAgencyOptions.length > 0
      ? providedAgencyOptions
      : buildMeetingSummaryIssueAgencies(issue);

  const [status, setStatus] = useState(() => getInitialIssueStatus(issue.status));
  const [issueEscalation, setIssueEscalation] = useState(() =>
    getEditableFieldValue(issue.issueEscalation),
  );
  const [rgcDecision, setRgcDecision] = useState(() =>
    getEditableFieldValue(issue.rgcDecision),
  );
  const [nextStep, setNextStep] = useState(() =>
    getEditableFieldValue(issue.nextStep),
  );
  const [remark, setRemark] = useState(() => getEditableFieldValue(issue.remark));
  const [secondAgency, setSecondAgency] = useState(() =>
    agencyDisplayNameToSelectId(getEditableFieldValue(issue.secondAgency), agencyOptions),
  );
  const [thirdAgency, setThirdAgency] = useState(() =>
    agencyDisplayNameToSelectId(getEditableFieldValue(issue.thirdAgency), agencyOptions),
  );
  const [fourthAgency, setFourthAgency] = useState(() =>
    agencyDisplayNameToSelectId(getEditableFieldValue(issue.fourthAgency), agencyOptions),
  );
  const [fifthAgency, setFifthAgency] = useState(() =>
    agencyDisplayNameToSelectId(getEditableFieldValue(issue.fifthAgency), agencyOptions),
  );
  const existingReference = getExistingIssueReference(issue.issueReference);
  const [attachment, setAttachment] = useState<File | null>(null);
  const [uploadStatus, setUploadStatus] = useState<UploadStatus>(() =>
    existingReference ? "completed" : "idle",
  );

  function handleFileSelect(file: File) {
    setAttachment(file);
    setUploadStatus("uploading");
    window.setTimeout(() => setUploadStatus("completed"), 800);
  }

  function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    if (file) handleFileSelect(file);
    event.target.value = "";
  }

  function handleDrop(event: DragEvent<HTMLDivElement>) {
    event.preventDefault();
    const file = event.dataTransfer.files?.[0];
    if (file) handleFileSelect(file);
  }

  function handleDragOver(event: DragEvent<HTMLDivElement>) {
    event.preventDefault();
  }

  function handleStatusChange(nextStatus: string) {
    setStatus(nextStatus);
    if (isSolvedStatus(nextStatus)) {
      setIssueEscalation("");
    }
  }

  const showIssueEscalation = !isSolvedStatus(status);

  async function handleSave() {
    const updatedIssue: ViewMeetingSummaryIssueRow = {
      ...issue,
      status: status || "New Submitted",
      issueEscalation: showIssueEscalation
        ? issueEscalation || "Not Uploaded"
        : "Not Uploaded",
      rgcDecision: rgcDecision.trim() || "Not Uploaded",
      nextStep: nextStep.trim() || "Not Uploaded",
      remark: remark.trim() || "Not Uploaded",
      secondAgency:
        agencySelectIdToDisplayName(secondAgency, agencyOptions) || "Not Uploaded",
      secondAgencyLogo: agencySelectIdToLogo(secondAgency, agencyOptions),
      thirdAgency:
        agencySelectIdToDisplayName(thirdAgency, agencyOptions) || "Not Uploaded",
      thirdAgencyLogo: agencySelectIdToLogo(thirdAgency, agencyOptions),
      fourthAgency:
        agencySelectIdToDisplayName(fourthAgency, agencyOptions) || "Not Uploaded",
      fourthAgencyLogo: agencySelectIdToLogo(fourthAgency, agencyOptions),
      fifthAgency:
        agencySelectIdToDisplayName(fifthAgency, agencyOptions) || "Not Uploaded",
      fifthAgencyLogo: agencySelectIdToLogo(fifthAgency, agencyOptions),
      issueReference: attachment ? attachment.name : issue.issueReference,
      // Carry the real agencies (numeric stakeholder ids) so the chosen agency
      // names can be resolved back to ids when persisting. Static/custom
      // options (non-numeric ids) are dropped.
      agencies: agencyOptions
        .map((option) => ({
          id: Number(option.id),
          name: option.name,
          logo: option.logo || null,
        }))
        .filter((option) => Number.isFinite(option.id) && option.id > 0),
    };

    setSaving(true);

    try {
      await onSave?.({ issue: updatedIssue, attachment });
      onClose();
    } finally {
      setSaving(false);
    }
  }

  return (
    <>
      <Box
        sx={{
          px: 3,
          pt: 2.5,
          pb: 2,
          borderBottom: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"}`,
        }}
      >
        <Typography
          sx={{
            fontSize: 20,
            fontWeight: 500,
            color: "#0a0a0a",
            letterSpacing: "-0.4px",
          }}
        >
          Update Issue
        </Typography>
        <Typography
          className={
            /[\u1780-\u17FF]/.test(issue.issue) ? "font-kh" : undefined
          }
          sx={{
            mt: 2.5,
            fontSize: 24,
            fontWeight: 600,
            color: "#181d27",
            lineHeight: 1.2,
          }}
        >
          {issue.issue}
        </Typography>
      </Box>

      <Box
        sx={{
          px: 3,
          py: 2.5,
          overflowY: "auto",
          maxHeight: "calc(100dvh - 180px)",
        }}
      >
        <SectionTitle>Submit Detail</SectionTitle>

        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" },
            columnGap: { md: "161px" },
            rowGap: 2,
            alignItems: "center",
            mb: 3,
            pb: 3,
            borderBottom: `1px solid ${getBorderColor(theme)}`,
          }}
        >
          <DetailItem icon={<AccountCircleIcon />} label="Submitted By">
            <Typography
              sx={{ fontSize: 13, fontWeight: 500, color: "#181d27" }}
            >
              {submittedBy}
            </Typography>
          </DetailItem>

          <DetailItem
            icon={<CategoryOfIssuesIcon />}
            label="Category of Issues"
          >
            <Typography
              sx={{ fontSize: 13, fontWeight: 500, color: "#181d27" }}
            >
              {issue.category}
            </Typography>
          </DetailItem>

          <DetailItem icon={<SubmitDateIcon />} label="Submitted Date">
            <Typography
              sx={{ fontSize: 13, fontWeight: 500, color: "#252b37" }}
            >
              {submittedDate}
            </Typography>
          </DetailItem>

          <Box
            sx={{
              display: "flex",
              alignItems: "center",
              gap: "11px",
              minWidth: 0,
              minHeight: 27,
            }}
          >
            <Box
              sx={{
                color: "#717680",
                display: "flex",
                flexShrink: 0,
                width: 20,
                height: 20,
                alignItems: "center",
                justifyContent: "center",
              }}
            >
              <HyperlinkIcon />
            </Box>
            <Box
              sx={{
                display: "flex",
                alignItems: "center",
                gap: "13px",
                minWidth: 0,
              }}
            >
              <Typography
                sx={{
                  fontSize: 13,
                  fontWeight: 400,
                  lineHeight: "22px",
                  color: "#717680",
                  whiteSpace: "nowrap",
                }}
              >
                Issue Document :
              </Typography>
              <DocumentFileAttachment
                value={issueDocument}
                fileSize={issueDocumentSize}
              />
            </Box>
          </Box>
        </Box>

        <SectionTitle>Issues Description</SectionTitle>
        <Typography
          className={
            /[\u1780-\u17FF]/.test(issue.issueDescription)
              ? "font-kh"
              : undefined
          }
          sx={{
            mb: 3,
            pb: 3,
            fontSize: 13,
            fontWeight: 500,
            color: "#181d27",
            lineHeight: 1.5,
            borderBottom: `1px solid ${getBorderColor(theme)}`,
          }}
        >
          {issue.issueDescription}
        </Typography>

        <SectionTitle>Recommendations</SectionTitle>
        <Typography
          className={
            /[\u1780-\u17FF]/.test(issue.recommendation) ? "font-kh" : undefined
          }
          sx={{
            mb: 3,
            pb: 3,
            fontSize: 13,
            fontWeight: 500,
            color: "#181d27",
            lineHeight: 1.5,
            borderBottom: `1px solid ${getBorderColor(theme)}`,
          }}
        >
          {issue.recommendation}
        </Typography>

        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", sm: "auto auto" },
            gap: 3,
            mb: 3,
          }}
        >
          <Box>
            <SectionTitle>Status</SectionTitle>
            <IssueStatusSelect
              value={status}
              menuZIndex={SELECT_MENU_Z_INDEX}
              onChange={handleStatusChange}
            />
          </Box>

          {showIssueEscalation ? (
            <Box>
              <SectionTitle>Issue Escalation</SectionTitle>
              <IssueEscalationSelect
                value={issueEscalation}
                menuZIndex={SELECT_MENU_Z_INDEX}
                onChange={setIssueEscalation}
              />
            </Box>
          ) : null}
        </Box>

        <Box sx={{ mb: 3 }}>
          <SectionTitle>RGC Decision</SectionTitle>
          <EditorBox
            placeholder="Write RGC Decision........."
            value={rgcDecision}
            onChange={setRgcDecision}
          />
        </Box>

        <Box sx={{ mb: 3 }}>
          <SectionTitle>Next Step</SectionTitle>
          <EditorBox
            placeholder="Write RGC Decision........."
            value={nextStep}
            onChange={setNextStep}
          />
        </Box>

        <Box sx={{ mb: 3 }}>
          <SectionTitle>Remark</SectionTitle>
          <EditorBox
            placeholder="Write RGC Decision........."
            value={remark}
            onChange={setRemark}
          />
        </Box>

        <Box sx={{ mb: 3 }}>
          <AdditionalAgencyFields
            agencies={agencyOptions}
            secondAgency={secondAgency}
            onSecondAgencyChange={setSecondAgency}
            thirdAgency={thirdAgency}
            onThirdAgencyChange={setThirdAgency}
            fourthAgency={fourthAgency}
            onFourthAgencyChange={setFourthAgency}
            fifthAgency={fifthAgency}
            onFifthAgencyChange={setFifthAgency}
            selectMenuProps={getElevatedSelectMenuProps(
              theme,
              SELECT_MENU_Z_INDEX,
            )}
          />
        </Box>

        <Box sx={{ mb: 2 }}>
          <Typography
            sx={{
              fontSize: 13,
              fontWeight: 500,
              color: "#414651",
              mb: 1.5,
            }}
          >
            Issues Reference
          </Typography>

          <IssuesReferenceUploadField
            attachment={attachment}
            existingReference={existingReference}
            fileInputRef={fileInputRef}
            uploadStatus={uploadStatus}
            onDragOver={handleDragOver}
            onDrop={handleDrop}
            onFileChange={handleFileChange}
            onUploadClick={() => fileInputRef.current?.click()}
          />
        </Box>
      </Box>

      <Box
        sx={{
          px: 3,
          py: 2.25,
          borderTop: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#ddedfb"}`,
          display: "flex",
          flexDirection: "column",
          alignItems: "flex-end",
          gap: 1,
          bgcolor: isDark ? "#101828" : "#ffffff",
        }}
      >
        {saveError ? (
          <Typography sx={{ width: "100%", fontSize: 12, color: "#f04438" }}>
            {saveError}
          </Typography>
        ) : null}

        <Box sx={{ display: "flex", justifyContent: "flex-end", gap: 1.5 }}>
          <AppCancelButton
            disabled={saving}
            onClick={onClose}
            sx={{ minWidth: 150, width: 150 }}
          >
            Cancel
          </AppCancelButton>

          <AppButton
            disabled={saving}
            onClick={() => void handleSave()}
            sx={{ minWidth: 150, width: 150 }}
          >
            {saving ? "Saving..." : "Save"}
          </AppButton>
        </Box>
      </Box>
    </>
  );
}

export function UpdateMeetingSummaryIssueDialog({
  open,
  issue,
  submittedBy = "-",
  submittedDate = "-",
  issueDocument = "Meeting Request DOC",
  issueDocumentSize = "200 KB",
  onClose,
  onSave,
  saveError,
  agencyOptions,
}: Props) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  if (!issue) return null;

  return (
    <Dialog
      open={open}
      onClose={onClose}
      maxWidth={false}
      scroll="paper"
      sx={{
        zIndex: DIALOG_Z_INDEX,
        "& .MuiBackdrop-root": { bgcolor: "rgba(0, 0, 0, 0.35)" },
      }}
      slotProps={{
        paper: {
          sx: {
            width: { xs: "calc(100vw - 24px)", md: 796 },
            maxWidth: "calc(100vw - 24px)",
            maxHeight: "calc(100dvh - 24px)",
            borderRadius: "12px",
            overflow: "hidden",
            bgcolor: isDark ? "#101828" : "#ffffff",
            backgroundImage: "none",
          },
        },
      }}
    >
      {open ? (
        <UpdateMeetingSummaryIssueDialogContent
          key={issue.id}
          issue={issue}
          submittedBy={submittedBy}
          submittedDate={submittedDate}
          issueDocument={issueDocument}
          issueDocumentSize={issueDocumentSize}
          onClose={onClose}
          onSave={onSave}
          saveError={saveError}
          agencyOptions={agencyOptions}
        />
      ) : null}
    </Dialog>
  );
}
