"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";

import Box from "@mui/material/Box";
import CircularProgress from "@mui/material/CircularProgress";
import Typography from "@mui/material/Typography";
import { useTheme } from "@mui/material/styles";

import { ToastNotification } from "@/components/ui/toast-notification";
import {
  buildAgencyStakeholderIdsForIssue,
  getMeetingSummaryById,
  mergeIssueRowAfterSave,
  shareMeetingSummaryWithPswg,
  updateMeetingSummary,
  upsertMeetingSummaryIssue,
} from "@/features/ministry/meeting-summary/meeting-summary-service";
import { getMeetingSummaryFont } from "@/features/ministry/meeting-summary/meeting-summary-i18n";
import { CreateMeetingSummaryHeader } from "@/features/ministry/meeting-summary/components/create-meeting-summary/create-meeting-summary-header";
import { CreateMeetingSummaryUploadSection } from "@/features/ministry/meeting-summary/components/create-meeting-summary/create-meeting-summary-upload-section";
import { MeetingSummaryParticipantsDialog } from "@/features/ministry/meeting-summary/components/meeting-summary-participants-dialog";
import { MeetingSummaryParticipantsTable } from "@/features/ministry/meeting-summary/components/meeting-summary-participants-table";
import type { ParticipantGroup } from "@/features/ministry/meeting-summary/components/meeting-summary-participants-table";
import { MeetingSummaryListOfIssueTable } from "@/features/ministry/meeting-summary/components/create-meeting-summary/table/meeting-summary-list-of-issue-table";
import { UpdateMeetingSummaryIssueDialog } from "@/features/ministry/meeting-summary/components/create-meeting-summary/update-meeting-summary-issue-dialog";
import type { UpdateMeetingSummaryIssueSavePayload } from "@/features/ministry/meeting-summary/components/create-meeting-summary/update-meeting-summary-issue-dialog";
import { ViewMeetingSummaryInfoSection } from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-info-section";
import { printMeetingSummaryLayout } from "@/features/ministry/meeting-summary/components/view-meeting-summary/print/meeting-summary-print-action";
import { buildMeetingSummaryPrintModel } from "@/features/ministry/meeting-summary/components/view-meeting-summary/print/meeting-summary-print-mock-data";
import { MeetingSummaryPrintView } from "@/features/ministry/meeting-summary/components/view-meeting-summary/print/meeting-summary-print-view";
import { ViewMeetingSummaryReferenceSection } from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-reference-section";
import type {
  ViewMeetingSummaryDetail,
  MeetingSummaryParticipants,
  ViewMeetingSummaryIssueRow,
} from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-data";

type Props = {
  summaryId: number;
  lang?: "en" | "km";
};

function hasUploadedReference(referenceName: string) {
  const trimmed = referenceName.trim();
  return trimmed !== "" && trimmed !== "Not Uploaded";
}

export function EditMeetingSummaryScreen({ summaryId, lang = "en" }: Props) {
  const router = useRouter();
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const isInvalidSummaryId = !Number.isFinite(summaryId) || summaryId <= 0;

  const [detail, setDetail] = useState<ViewMeetingSummaryDetail | null>(null);
  const [fetchLoading, setFetchLoading] = useState(!isInvalidSummaryId);
  const [fetchError, setFetchError] = useState<string | null>(null);
  const loading = isInvalidSummaryId ? false : fetchLoading;
  const error = isInvalidSummaryId
    ? "Meeting summary not found."
    : fetchError;
  const [referenceFile, setReferenceFile] = useState<File | null>(null);
  const [saving, setSaving] = useState<"draft" | "submit" | null>(null);
  const [selectedIssue, setSelectedIssue] =
    useState<ViewMeetingSummaryIssueRow | null>(null);
  const [updateIssueOpen, setUpdateIssueOpen] = useState(false);
  const [issueSaveError, setIssueSaveError] = useState<string | null>(null);
  const [issuesTableKey, setIssuesTableKey] = useState(0);
  const [sharing, setSharing] = useState(false);
  const [shareToast, setShareToast] = useState<string | null>(null);
  const [participantsDialogOpen, setParticipantsDialogOpen] = useState(false);
  const [selectedParticipantGroup, setSelectedParticipantGroup] =
    useState<ParticipantGroup | null>(null);
  const [participantSaveError, setParticipantSaveError] = useState<string | null>(
    null,
  );
  const printModel = useMemo(
    () => buildMeetingSummaryPrintModel(detail, { useMockIssues: true }),
    [detail],
  );

  useEffect(() => {
    if (isInvalidSummaryId) return;

    let cancelled = false;

    async function loadSummary() {
      setFetchLoading(true);
      setFetchError(null);

      try {
        const data = await getMeetingSummaryById(summaryId);
        if (cancelled) return;
        setDetail(data);
      } catch {
        if (cancelled) return;
        setFetchError("Could not load meeting summary.");
      } finally {
        if (!cancelled) setFetchLoading(false);
      }
    }

    void loadSummary();

    return () => {
      cancelled = true;
    };
  }, [isInvalidSummaryId, summaryId]);

  function handleBack() {
    router.push("/ministry/meeting-summary");
  }

  function handleOpenParticipantsDialog() {
    setParticipantSaveError(null);
    setSelectedParticipantGroup(null);
    setParticipantsDialogOpen(true);
  }

  function handleUpdateParticipants(group: ParticipantGroup) {
    setParticipantSaveError(null);
    setSelectedParticipantGroup(group);
    setParticipantsDialogOpen(true);
  }

  function handleCloseParticipantsDialog() {
    setParticipantsDialogOpen(false);
    setParticipantSaveError(null);
    setSelectedParticipantGroup(null);
  }

  async function handleSaveParticipants(
    participants: MeetingSummaryParticipants,
  ) {
    setParticipantSaveError(null);

    try {
      await updateMeetingSummary(summaryId, { participants });
      setDetail((current) =>
        current ? { ...current, participants } : current,
      );
    } catch (saveError) {
      const message =
        saveError instanceof Error
          ? saveError.message
          : "Could not save participants.";
      setParticipantSaveError(message);
      throw saveError;
    }
  }

  async function handleSave(kind: "draft" | "submit") {
    if (!detail) return;

    setSaving(kind);
    setFetchError(null);

    try {
      const status =
        kind === "submit"
          ? "SUBMITTED"
          : detail.status === "REVIEWED"
            ? "REVIEWED"
            : "DRAFT";

      await updateMeetingSummary(summaryId, {
        file: referenceFile,
        status,
        issues: detail.issues,
        participants: detail.participants,
      });

      if (kind === "submit") {
        router.push("/ministry/meeting-summary?toast=submit-cdc");
        return;
      }

      if (detail.status === "REVIEWED") {
        const data = await getMeetingSummaryById(summaryId);
        setDetail(data);
        setReferenceFile(null);
        setSaving(null);
        return;
      }

      router.push("/ministry/meeting-summary");
    } catch (saveError) {
      setFetchError(
        saveError instanceof Error
          ? saveError.message
          : "Could not save meeting summary.",
      );
      setSaving(null);
    }
  }

  async function handleShareToggle() {
    if (!detail || detail.share || sharing) return;

    setSharing(true);

    try {
      await shareMeetingSummaryWithPswg(summaryId);
      setShareToast("Shared with PSWG.");

      setDetail((current) =>
        current ? { ...current, share: true } : current,
      );
    } catch (shareError) {
      setFetchError(
        shareError instanceof Error
          ? shareError.message
          : "Could not update PSWG sharing.",
      );
      throw shareError;
    } finally {
      setSharing(false);
    }
  }

  function handleUpdateIssue(issue: ViewMeetingSummaryIssueRow) {
    setIssueSaveError(null);
    setSelectedIssue(issue);
    setUpdateIssueOpen(true);
  }

  function handleCloseUpdateIssue() {
    setUpdateIssueOpen(false);
    setSelectedIssue(null);
    setIssueSaveError(null);
  }

  async function handleSaveIssue({
    issue,
    attachment,
  }: UpdateMeetingSummaryIssueSavePayload) {
    if (!detail) return;

    setIssueSaveError(null);

    try {
      const savedIssue = await upsertMeetingSummaryIssue(
        summaryId,
        issue.id,
        {
          status: issue.status,
          issueEscalation: issue.issueEscalation,
          rgcDecision: issue.rgcDecision,
          nextStep: issue.nextStep,
          remark: issue.remark,
          attachment,
          agencyStakeholderIds: buildAgencyStakeholderIdsForIssue(issue),
        },
        detail.privateSectorWg,
      );

      setDetail((current) =>
        current
          ? {
              ...current,
              issues: current.issues.map((row) =>
                row.id === issue.id
                  ? mergeIssueRowAfterSave(row, issue, savedIssue)
                  : row,
              ),
            }
          : current,
      );
      setIssuesTableKey((current) => current + 1);
    } catch (saveError) {
      setIssueSaveError(
        saveError instanceof Error
          ? saveError.message
          : "Could not save issue resolution.",
      );
      throw saveError;
    }
  }

  const hasExistingReference = detail
    ? hasUploadedReference(detail.summaryReference.name)
    : false;
  const hasReferenceReady = Boolean(referenceFile) || hasExistingReference;
  const isReviewed = detail?.status === "REVIEWED";
  const showSubmitToCdc = isReviewed;

  return (
    <Box
      sx={{
        "--ms-text": isDark ? "#E5E7EB" : "#181d27",
        "--ms-muted": isDark ? "#CBD5E1" : "#717680",
        "--ms-subtle": isDark ? "#9CA3AF" : "#414651",
        "--ms-secondary": isDark ? "#E5E7EB" : "#252b37",
        "--ms-border": isDark ? "#374151" : "#e9eaeb",
        "--ms-blue": isDark ? "#60A5FA" : "#1a64a8",
        "--ms-blue-dark": isDark ? "#3B82F6" : "#155489",
        "--ms-chip-bg": isDark ? "#1E3A5F" : "#edf8fd",
        "--ms-chip-border": isDark ? "#4D87C7" : "#b6dbf6",
        "--ms-surface": isDark ? "#111827" : "#fafafa",
        "--ms-surface-track": isDark ? "#1F2937" : "#ffffff",
        minHeight: "100%",
        width: "100%",
        minWidth: 0,
        px: { xs: 2, md: 3 },
        py: { xs: 2, md: 3 },
        color: "var(--ms-text)",
        fontFamily: getMeetingSummaryFont(lang),
        overflowX: "hidden",
      }}
    >
      <CreateMeetingSummaryHeader
        mode="edit"
        onBack={handleBack}
        onSaveDraft={() => handleSave("draft")}
        onSubmitToCdc={() => handleSave("submit")}
        showSubmitToCdc={showSubmitToCdc}
        showSaveDraft
        saveDraftLabel={isReviewed ? "Save" : "Save Draft"}
        submitDisabled={!hasReferenceReady}
        saveDraftDisabled={!detail}
        isSavingDraft={saving === "draft"}
        isSubmitting={saving === "submit"}
        shared={detail?.share ?? false}
        onShareConfirm={handleShareToggle}
        isSharing={sharing}
      />

      {loading ? (
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            minHeight: 320,
          }}
        >
          <CircularProgress size={32} />
        </Box>
      ) : error || !detail ? (
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            minHeight: 320,
          }}
        >
          <Typography sx={{ fontSize: 14, color: "var(--ms-muted)" }}>
            {error ?? "Meeting summary not found."}
          </Typography>
        </Box>
      ) : (
        <>
          <ViewMeetingSummaryInfoSection detail={detail} />

          <MeetingSummaryListOfIssueTable
            key={issuesTableKey}
            rows={detail.issues}
            onPrint={printMeetingSummaryLayout}
            onUpdateIssue={handleUpdateIssue}
          />

          <MeetingSummaryParticipantsTable
            participants={detail.participants}
            onAddParticipants={handleOpenParticipantsDialog}
            onUpdateParticipants={handleUpdateParticipants}
          />

          <MeetingSummaryPrintView model={printModel} />

          {isReviewed && hasExistingReference && !referenceFile ? (
            <ViewMeetingSummaryReferenceSection
              reference={detail.summaryReference}
            />
          ) : null}

          {isReviewed ? (
            <CreateMeetingSummaryUploadSection
              file={referenceFile}
              onFileSelect={setReferenceFile}
            />
          ) : null}

          <UpdateMeetingSummaryIssueDialog
            open={updateIssueOpen}
            issue={selectedIssue}
            submittedBy={detail.sentBy}
            submittedDate={detail.date}
            issueDocument={detail.meetingRequestDocument}
            issueDocumentSize={detail.meetingRequestDocumentSize}
            onClose={handleCloseUpdateIssue}
            onSave={handleSaveIssue}
            saveError={issueSaveError}
          />

          <MeetingSummaryParticipantsDialog
            open={participantsDialogOpen}
            participants={detail.participants}
            onClose={handleCloseParticipantsDialog}
            onSave={handleSaveParticipants}
            saveError={participantSaveError}
            group={selectedParticipantGroup}
          />
        </>
      )}

      <ToastNotification
        open={Boolean(shareToast)}
        message={shareToast ?? ""}
        onClose={() => setShareToast(null)}
      />
    </Box>
  );
}
