"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter, useSearchParams } 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 { getMeetingById } from "@/features/ministry/meeting-calendar/meeting-calendar-service";
import {
  buildAgencyStakeholderIdsForIssue,
  createMeetingSummary,
  getMeetingSummaryAgencies,
  mergeIssueRowAfterSave,
  updateMeetingSummary,
  upsertMeetingSummaryIssue,
} from "@/features/ministry/meeting-summary/meeting-summary-service";
import type { Agency } from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/add-dashboard-issue-dialog-types";
import { getMeetingSummaryFont } from "@/features/ministry/meeting-summary/meeting-summary-i18n";
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 type { ViewMeetingSummaryDetail } from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-data";

import { CreateMeetingSummaryHeader } from "./create-meeting-summary-header";
import { mapMeetingToSummaryDetail } from "./create-meeting-summary-mapper";
import { MeetingSummaryListOfIssueTable } from "./table/meeting-summary-list-of-issue-table";
import { UpdateMeetingSummaryIssueDialog } from "./update-meeting-summary-issue-dialog";
import { MeetingSummaryParticipantsDialog } from "../meeting-summary-participants-dialog";
import { MeetingSummaryParticipantsTable } from "../meeting-summary-participants-table";
import type { ParticipantGroup } from "../meeting-summary-participants-table";
import type { UpdateMeetingSummaryIssueSavePayload } from "./update-meeting-summary-issue-dialog";
import {
  EMPTY_MEETING_SUMMARY_PARTICIPANTS,
  type MeetingSummaryParticipants,
  type ViewMeetingSummaryIssueRow,
} from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-data";

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

export function CreateMeetingSummaryScreen({ lang = "en" }: Props) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  const meetingId = Number(searchParams.get("meetingId"));
  const isInvalidMeetingId = !Number.isFinite(meetingId) || meetingId <= 0;

  const [detail, setDetail] = useState<ViewMeetingSummaryDetail | null>(null);
  const [fetchLoading, setFetchLoading] = useState(!isInvalidMeetingId);
  const [fetchError, setFetchError] = useState<string | null>(null);
  const loading = isInvalidMeetingId ? false : fetchLoading;
  const error = isInvalidMeetingId ? "Meeting not found." : fetchError;
  const [savingDraft, setSavingDraft] = useState(false);
  const [selectedIssue, setSelectedIssue] =
    useState<ViewMeetingSummaryIssueRow | null>(null);
  const [updateIssueOpen, setUpdateIssueOpen] = useState(false);
  const [meetingSummaryId, setMeetingSummaryId] = useState<number | null>(null);
  const [issueSaveError, setIssueSaveError] = useState<string | null>(null);
  const [issuesTableKey, setIssuesTableKey] = useState(0);
  const [agencyOptions, setAgencyOptions] = useState<Agency[]>([]);
  const [participants, setParticipants] = useState(
    EMPTY_MEETING_SUMMARY_PARTICIPANTS,
  );
  const [participantsDialogOpen, setParticipantsDialogOpen] = useState(false);
  const [selectedParticipantGroup, setSelectedParticipantGroup] =
    useState<ParticipantGroup | null>(null);
  const [participantSaveError, setParticipantSaveError] = useState<string | null>(
    null,
  );
  const printModel = useMemo(
    () => buildMeetingSummaryPrintModel(detail),
    [detail],
  );

  // Load the real government agencies once so the Update Issue dialog can offer
  // them (with real stakeholder ids) in its agency dropdowns.
  useEffect(() => {
    let active = true;

    getMeetingSummaryAgencies()
      .then((agencies) => {
        if (active) setAgencyOptions(agencies);
      })
      .catch(() => {
        if (active) setAgencyOptions([]);
      });

    return () => {
      active = false;
    };
  }, []);

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

    let cancelled = false;

    async function loadMeeting() {
      let isRedirecting = false;
      setFetchLoading(true);
      setFetchError(null);

      try {
        const meeting = await getMeetingById(meetingId);
        if (cancelled) return;

        if (meeting.meetingSummaryId) {
          isRedirecting = true;
          router.replace(
            `/ministry/meeting-summary/${meeting.meetingSummaryId}`,
          );
          return;
        }

        setDetail(mapMeetingToSummaryDetail(meeting));
      } catch {
        if (cancelled) return;
        setFetchError("Could not load meeting details.");
      } finally {
        if (!cancelled && !isRedirecting) setFetchLoading(false);
      }
    }

    void loadMeeting();

    return () => {
      cancelled = true;
    };
  }, [isInvalidMeetingId, meetingId, router]);

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

  // Save Draft creates the summary and returns to the list.
  async function ensureMeetingSummaryDraft(
    participantsToSave = participants,
  ): Promise<number> {
    if (meetingSummaryId != null) return meetingSummaryId;

    const id = await createMeetingSummary({
      meetingId,
      status: "DRAFT",
      participants: participantsToSave,
    });
    setMeetingSummaryId(id);
    return id;
  }

  async function handleSaveDraft() {
    if (!Number.isFinite(meetingId) || meetingId <= 0 || !detail) return;

    setSavingDraft(true);
    setFetchError(null);

    try {
      if (meetingSummaryId != null) {
        await updateMeetingSummary(meetingSummaryId, {
          status: "DRAFT",
          issues: detail.issues,
          participants,
        });
      } else {
        const id = await createMeetingSummary({
          meetingId,
          status: "DRAFT",
          issues: detail.issues,
          participants,
        });
        setMeetingSummaryId(id);
      }

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

  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(
    nextParticipants: MeetingSummaryParticipants,
  ) {
    setParticipantSaveError(null);

    try {
      const isNewSummary = meetingSummaryId == null;
      const summaryId = await ensureMeetingSummaryDraft(nextParticipants);

      if (!isNewSummary) {
        await updateMeetingSummary(summaryId, {
          participants: nextParticipants,
        });
      }

      setParticipants(nextParticipants);
    } catch (saveError) {
      const message =
        saveError instanceof Error
          ? saveError.message
          : "Could not save participants.";
      setParticipantSaveError(message);
      throw saveError;
    }
  }

  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 summaryId = await ensureMeetingSummaryDraft();
      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;
    }
  }

  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
        onBack={handleBack}
        onSaveDraft={handleSaveDraft}
        showSubmitToCdc={false}
        saveDraftDisabled={!detail}
        isSavingDraft={savingDraft}
      />

      {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 not found."}
          </Typography>
        </Box>
      ) : (
        <>
          <ViewMeetingSummaryInfoSection detail={detail} />

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

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

          <MeetingSummaryPrintView model={printModel} />

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

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