"use client";

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

import Box from "@mui/material/Box";
import Drawer from "@mui/material/Drawer";
import IconButton from "@mui/material/IconButton";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import { alpha, useTheme, type Theme } from "@mui/material/styles";

import CloseIcon from "@mui/icons-material/Close";

import { AppButton } from "@/components/ui/button";
import { AppDatePicker } from "@/components/ui/date-picker";
import { DocumentLink } from "@/components/ui/document-link";
import {
  getElevatedSelectMenuProps,
  getInputSx,
} from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/add-dashboard-issue-dialog-styles";
import type { UploadStatus } from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/add-dashboard-issue-dialog-types";
import { AgencySelect } from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/agency-select";
import { EditorBox } from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/editor-box";
import {
  IssueReferenceFileCard,
  IssuesReferenceUploadField,
} from "@/features/ministry/meeting-summary/components/create-meeting-summary/issues-reference-upload-field";
import {
  IssueStatusSelect,
  getInitialIssueStatus,
} from "@/features/ministry/meeting-summary/components/create-meeting-summary/issue-status-select";
import {
  formatFileSize,
  type UploadedFileMetadata,
} from "@/lib/document-file";
import { format, isValid, parse } from "date-fns";

import {
  agencyDisplayNameToSelectId,
  agencySelectIdToDisplayName,
  agencySelectIdToLogo,
  buildProgressReportDecisionAgencies,
  getEditableFieldValue,
} from "./progress-report-decision-agencies";
import type { MinistryProgressReportDecisionRow } from "./progress-report-decisions-data";

const DRAWER_Z_INDEX = 1700;
const SELECT_MENU_Z_INDEX = DRAWER_Z_INDEX + 100;
const DATE_PICKER_Z_INDEX = DRAWER_Z_INDEX + 100;
const MAX_PDF_SIZE_BYTES = 10 * 1024 * 1024;

export type UpdateProgressReportDecisionSavePayload = {
  decision: MinistryProgressReportDecisionRow;
  status: MinistryProgressReportDecisionRow["status"];
  indicators?: string;
  progressSolution?: string;
  implementationChallenges?: string;
  requests?: string;
  sourceOfVerification?: string;
  linkToVerificationSource?: string;
  nextStep?: string;
  dateOfIssueSolution?: string;
  attachment: File | null;
};

type Props = {
  open: boolean;
  decision: MinistryProgressReportDecisionRow | null;
  onClose: () => void;
  onSave?: (
    payload: UpdateProgressReportDecisionSavePayload,
  ) => void | Promise<void>;
  readOnly?: boolean;
  onAddComment?: () => void;
  decisionAttachment?: UploadedFileMetadata | null;
};

function DrawerFieldLabel({
  children,
  required = false,
}: {
  children: ReactNode;
  required?: boolean;
}) {
  return (
    <Typography
      sx={{
        fontSize: 13,
        fontWeight: 500,
        color: "#414651",
        mb: "14px",
        lineHeight: 1,
      }}
    >
      {children}
      {required ? (
        <Box component="span" sx={{ color: "#ef4444" }}>
          {" "}
          *
        </Box>
      ) : null}
    </Typography>
  );
}

function getDrawerInputSx(theme: Theme) {
  return {
    ...getInputSx(theme),
    "& .MuiOutlinedInput-root": {
      height: 50,
      borderRadius: "6px",
      bgcolor: theme.palette.background.paper,
      color: theme.palette.text.primary,
      fontSize: 12,
    },
    "& .MuiInputBase-input": {
      fontSize: 12,
      py: 0,
    },
  };
}

function parseSolutionDate(value: string): Date | null {
  const trimmed = getEditableFieldValue(value);
  if (!trimmed) return null;

  const formats = [
    "yyyy-MM-dd",
    "MMMM dd, yyyy",
    "MMMM d, yyyy",
    "dd MMMM yyyy",
  ];
  for (const pattern of formats) {
    const parsed = parse(trimmed, pattern, new Date());
    if (isValid(parsed)) return parsed;
  }

  const fallback = new Date(trimmed);
  return isValid(fallback) ? fallback : null;
}

function formatSolutionDate(date: Date | null): string {
  if (!date || !isValid(date)) return "No data";
  return format(date, "MMMM dd, yyyy");
}

function DecisionEditorField({
  label,
  onChange,
  placeholder,
  readOnly,
  required = false,
  value,
}: {
  label: string;
  onChange: (value: string) => void;
  placeholder: string;
  readOnly: boolean;
  required?: boolean;
  value: string;
}) {
  return (
    <Box>
      <DrawerFieldLabel required={required}>{label}</DrawerFieldLabel>
      <EditorBox
        placeholder={placeholder}
        value={value}
        onChange={onChange}
        readOnly={readOnly}
      />
    </Box>
  );
}

function ReadOnlyAttachmentField({
  attachment,
}: {
  attachment: UploadedFileMetadata | null | undefined;
}) {
  return (
    <Box sx={{ maxWidth: 375 }}>
      <DrawerFieldLabel>Attachment</DrawerFieldLabel>
      {attachment?.name?.trim() ? (
        <DocumentLink file={attachment}>
          <IssueReferenceFileCard
            name={attachment.name}
            sizeLabel={formatFileSize(attachment.size)}
            uploadStatus="completed"
          />
        </DocumentLink>
      ) : (
        <Box
          sx={{
            height: 62,
            borderRadius: "6px",
            border: "1px solid #e9eaeb",
            bgcolor: "#fafafa",
          }}
        />
      )}
    </Box>
  );
}

type DrawerContentProps = {
  decision: MinistryProgressReportDecisionRow;
  onClose: () => void;
  onSave?: (
    payload: UpdateProgressReportDecisionSavePayload,
  ) => void | Promise<void>;
  readOnly: boolean;
  onAddComment?: () => void;
  decisionAttachment?: UploadedFileMetadata | null;
};

function UpdateProgressReportDecisionDrawerContent({
  decision,
  onClose,
  onSave,
  readOnly,
  onAddComment,
  decisionAttachment,
}: DrawerContentProps) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const fileInputRef = useRef<HTMLInputElement>(null);

  const agencyOptions = buildProgressReportDecisionAgencies(decision);
  const selectMenuProps = getElevatedSelectMenuProps(theme, SELECT_MENU_Z_INDEX);

  const [saving, setSaving] = useState(false);
  const [primaryAgency, setPrimaryAgency] = useState(() =>
    agencyDisplayNameToSelectId(decision.primaryAgency, agencyOptions),
  );
  const [status, setStatus] = useState(() =>
    getInitialIssueStatus(decision.status),
  );
  const [category, setCategory] = useState(decision.category);
  const [focalPerson, setFocalPerson] = useState(decision.focalPerson);
  const [rgcDecision, setRgcDecision] = useState(decision.rgcDecision);
  const [progressSolution, setProgressSolution] = useState(() =>
    getEditableFieldValue(decision.progressSolution),
  );
  const [indicators, setIndicators] = useState(() =>
    getEditableFieldValue(decision.indicators),
  );
  const [implementationChallenges, setImplementationChallenges] = useState(() =>
    getEditableFieldValue(decision.implementationChallenges),
  );
  const [request, setRequest] = useState(() =>
    getEditableFieldValue(decision.request),
  );
  const [sourceOfVerification, setSourceOfVerification] = useState(() =>
    getEditableFieldValue(decision.sourceOfVerification),
  );
  const [linkToVerificationSource, setLinkToVerificationSource] = useState(() =>
    getEditableFieldValue(decision.linkToVerificationSource),
  );
  const [nextStep, setNextStep] = useState(() =>
    getEditableFieldValue(decision.nextStep),
  );
  const [dateOfIssueSolution, setDateOfIssueSolution] = useState<Date | null>(() =>
    parseSolutionDate(decision.dateOfIssueSolution),
  );
  const [attachment, setAttachment] = useState<File | null>(null);
  const [uploadStatus, setUploadStatus] = useState<UploadStatus>("idle");
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [saveError, setSaveError] = useState<string | null>(null);

  function handleFileSelect(file: File) {
    if (file.type !== "application/pdf" && !file.name.toLowerCase().endsWith(".pdf")) {
      setUploadError("Only PDF files are supported.");
      return;
    }

    if (file.size > MAX_PDF_SIZE_BYTES) {
      setUploadError("PDF file must be 10 MB or smaller.");
      return;
    }

    setUploadError(null);
    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 toStoredValue(value: string) {
    const trimmed = value.trim();
    return trimmed || "No data";
  }

  async function handleSave() {
    if (!status) {
      setSaveError("Please select a valid status.");
      return;
    }

    const updatedDecision: MinistryProgressReportDecisionRow = {
      ...decision,
      primaryAgency:
        agencySelectIdToDisplayName(primaryAgency, agencyOptions) ||
        decision.primaryAgency,
      primaryAgencyLogo: agencySelectIdToLogo(primaryAgency, agencyOptions),
      pswg: decision.pswg,
      status: (status || decision.status) as MinistryProgressReportDecisionRow["status"],
      secondAgency: decision.secondAgency,
      secondAgencyLogo: decision.secondAgencyLogo,
      thirdAgency: decision.thirdAgency,
      thirdAgencyLogo: decision.thirdAgencyLogo,
      fourthAgency: decision.fourthAgency,
      fourthAgencyLogo: decision.fourthAgencyLogo,
      fifthAgency: decision.fifthAgency,
      fifthAgencyLogo: decision.fifthAgencyLogo,
      category: category.trim() || decision.category,
      focalPerson: focalPerson.trim() || decision.focalPerson,
      rgcDecision: rgcDecision.trim() || decision.rgcDecision,
      progressSolution: toStoredValue(progressSolution),
      indicators: toStoredValue(indicators),
      implementationChallenges: toStoredValue(implementationChallenges),
      request: toStoredValue(request),
      sourceOfVerification: toStoredValue(sourceOfVerification),
      linkToVerificationSource: toStoredValue(linkToVerificationSource),
      nextStep: toStoredValue(nextStep),
      dateOfIssueSolution: formatSolutionDate(dateOfIssueSolution),
    };

    setSaving(true);
    setSaveError(null);

    try {
      await onSave?.({
        decision: updatedDecision,
        status: updatedDecision.status,
        indicators: indicators.trim() || undefined,
        progressSolution: progressSolution.trim() || undefined,
        implementationChallenges:
          implementationChallenges.trim() || undefined,
        requests: request.trim() || undefined,
        sourceOfVerification: sourceOfVerification.trim() || undefined,
        linkToVerificationSource:
          linkToVerificationSource.trim() || undefined,
        nextStep: nextStep.trim() || undefined,
        dateOfIssueSolution: dateOfIssueSolution
          ? format(dateOfIssueSolution, "yyyy-MM-dd")
          : undefined,
        attachment,
      });
      onClose();
    } catch (error) {
      setSaveError(
        error instanceof Error
          ? error.message
          : "Unable to save the RGC Decision update.",
      );
    } finally {
      setSaving(false);
    }
  }

  const inputSx = getDrawerInputSx(theme);
  const readOnlySelectFieldSx = {
    pointerEvents: "none" as const,
    "& .MuiSelect-icon": { display: "none" },
  };

  return (
    <Box
      sx={{
        display: "flex",
        flexDirection: "column",
        height: "100%",
        minHeight: 0,
      }}
    >
      <Box
        sx={{
          height: 67,
          px: "22px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          borderBottom: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"}`,
          flexShrink: 0,
        }}
      >
        <Typography
          sx={{
            fontSize: 20,
            fontWeight: 500,
            color: "#0a0a0a",
            letterSpacing: "-0.4px",
            lineHeight: 1.2,
          }}
        >
          {readOnly ? "RGC Decision Info" : "Update RGC Decision"}
        </Typography>

        <IconButton onClick={onClose} size="small" sx={{ color: "#717680" }}>
          <CloseIcon sx={{ fontSize: 24 }} />
        </IconButton>
      </Box>

      <Box
        sx={{
          px: "18px",
          py: "22px",
          overflowY: "auto",
          flex: 1,
          minHeight: 0,
        }}
      >
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" },
            gap: "22px",
            mb: "22px",
          }}
        >
          <Box sx={readOnly ? readOnlySelectFieldSx : undefined}>
            <AgencySelect
              agencies={agencyOptions}
              label="Ministry *"
              value={primaryAgency}
              onChange={setPrimaryAgency}
              menuProps={selectMenuProps}
              emptyLabel={readOnly ? "" : undefined}
            />
          </Box>

          <Box sx={readOnly ? readOnlySelectFieldSx : undefined}>
            <DrawerFieldLabel>Status</DrawerFieldLabel>
            <IssueStatusSelect
              value={status}
              menuZIndex={SELECT_MENU_Z_INDEX}
              onChange={setStatus}
              placeholder={readOnly ? "" : undefined}
              sx={{
                width: "100%",
                height: 40,
                minWidth: 0,
                bgcolor: theme.palette.background.paper,
                "& .MuiSelect-select": {
                  height: 40,
                  minHeight: "40px !important",
                  py: 0,
                  display: "flex",
                  alignItems: "center",
                },
              }}
            />
          </Box>
        </Box>

        <Box sx={{ display: "grid", gap: "42px" }}>
          <Box
            sx={{
              display: "grid",
              gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" },
              gap: "22px",
            }}
          >
            <Box>
              <DrawerFieldLabel required>Issue Category</DrawerFieldLabel>
              <TextField
                fullWidth
                value={category}
                onChange={(event) => setCategory(event.target.value)}
                slotProps={{ input: { readOnly } }}
                sx={inputSx}
              />
            </Box>

            <Box>
              <DrawerFieldLabel required>Focal Person (H.E)</DrawerFieldLabel>
              <TextField
                fullWidth
                value={focalPerson}
                onChange={(event) => setFocalPerson(event.target.value)}
                slotProps={{ input: { readOnly } }}
                sx={inputSx}
              />
            </Box>
          </Box>

          <DecisionEditorField
            label="RGC Decision"
            required
            placeholder="Write RGC Decision........."
            readOnly={readOnly}
            value={rgcDecision}
            onChange={setRgcDecision}
          />

          <DecisionEditorField
            label="Progress Solution"
            required
            placeholder="Write progress solution........."
            readOnly={readOnly}
            value={progressSolution}
            onChange={setProgressSolution}
          />

          <DecisionEditorField
            label="Solution Indicators"
            required
            placeholder="Write indicators........."
            readOnly={readOnly}
            value={indicators}
            onChange={setIndicators}
          />

          <DecisionEditorField
            label="Implementation Challenges"
            required
            placeholder="Write implementation challenges........."
            readOnly={readOnly}
            value={implementationChallenges}
            onChange={setImplementationChallenges}
          />

          <DecisionEditorField
            label="Requests"
            required
            placeholder="Write requests........."
            readOnly={readOnly}
            value={request}
            onChange={setRequest}
          />

          <DecisionEditorField
            label="Source of Verification"
            placeholder="Write source of verification........."
            readOnly={readOnly}
            value={sourceOfVerification}
            onChange={setSourceOfVerification}
          />

          <Box>
            <DrawerFieldLabel>Link to Verification Source</DrawerFieldLabel>
            <TextField
              fullWidth
              value={linkToVerificationSource}
              onChange={(event) =>
                setLinkToVerificationSource(event.target.value)
              }
              placeholder={
                readOnly ? "" : "Enter Link to Verification Source"
              }
              slotProps={{ input: { readOnly } }}
              sx={{
                ...inputSx,
                "& .MuiInputBase-input": {
                  fontSize: 13,
                  fontWeight: 500,
                  py: 0,
                  "&::placeholder": {
                    color: "#717680",
                    opacity: 1,
                  },
                },
                "& .MuiOutlinedInput-root fieldset": {
                  borderColor: "#d5d7da",
                },
              }}
            />
          </Box>

          <DecisionEditorField
            label="Next Step"
            placeholder="Write next step........."
            readOnly={readOnly}
            value={nextStep}
            onChange={setNextStep}
          />

          <Box
            sx={
              readOnly
                ? { maxWidth: 238, pointerEvents: "none" }
                : { maxWidth: 238 }
            }
          >
            <DrawerFieldLabel>Date of Issue Solution</DrawerFieldLabel>
            <AppDatePicker
              value={dateOfIssueSolution}
              onChange={setDateOfIssueSolution}
              placeholder={readOnly ? "" : "Select date"}
              popperZIndex={DATE_PICKER_Z_INDEX}
            />
          </Box>

          {readOnly ? (
            <ReadOnlyAttachmentField attachment={decisionAttachment} />
          ) : (
            <Box sx={{ maxWidth: 375 }}>
              <DrawerFieldLabel>Attachment</DrawerFieldLabel>
              <IssuesReferenceUploadField
                attachment={attachment}
                existingReference={
                  decisionAttachment
                    ? {
                        name: decisionAttachment.name,
                        size: formatFileSize(decisionAttachment.size),
                        path: decisionAttachment.path,
                      }
                    : null
                }
                fileInputRef={fileInputRef}
                uploadStatus={uploadStatus}
                onDragOver={handleDragOver}
                onDrop={handleDrop}
                onFileChange={handleFileChange}
                onUploadClick={() => fileInputRef.current?.click()}
              />
              {uploadError ? (
                <Typography sx={{ mt: 1, fontSize: 12, color: "#f04438" }}>
                  {uploadError}
                </Typography>
              ) : null}
            </Box>
          )}

          {saveError ? (
            <Typography sx={{ fontSize: 12, color: "#f04438" }}>
              {saveError}
            </Typography>
          ) : null}
        </Box>
      </Box>

      {!readOnly || onAddComment ? (
        <Box
          sx={{
            height: 84,
            px: "22px",
            display: "flex",
            alignItems: "center",
            justifyContent: "flex-end",
            borderTop: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#ddedfb"}`,
            flexShrink: 0,
            bgcolor: isDark ? "#101828" : "#ffffff",
          }}
        >
          <AppButton
            disabled={!readOnly && saving}
            onClick={() => (readOnly ? onAddComment?.() : void handleSave())}
            sx={{
              minWidth: 150,
              width: 150,
              height: 40,
              bgcolor: "#1a64a8",
              "&:hover": { bgcolor: "#155a96" },
            }}
          >
            {readOnly ? "Add Comment" : saving ? "Saving..." : "Save"}
          </AppButton>
        </Box>
      ) : null}
    </Box>
  );
}

export function ProgressReportRgcDecisionInfoDrawer({
  open,
  decision,
  onClose,
  onAddComment,
  decisionAttachment,
}: Pick<
  Props,
  "open" | "decision" | "onClose" | "onAddComment" | "decisionAttachment"
>) {
  return (
    <UpdateProgressReportDecisionDrawer
      open={open}
      decision={decision}
      onClose={onClose}
      onAddComment={onAddComment}
      decisionAttachment={decisionAttachment}
      readOnly
    />
  );
}

export function UpdateProgressReportDecisionDrawer({
  open,
  decision,
  onClose,
  onSave,
  readOnly = false,
  onAddComment,
  decisionAttachment,
}: Props) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  return (
    <Drawer
      anchor="right"
      open={open && Boolean(decision)}
      onClose={onClose}
      sx={{
        zIndex: DRAWER_Z_INDEX,
        "& .MuiBackdrop-root": { bgcolor: "rgba(0, 0, 0, 0.35)" },
        "& .MuiDrawer-paper": {
          width: { xs: "100vw", sm: 795 },
          maxWidth: "100vw",
          height: "100dvh",
          borderRadius: "12px 0 0 12px",
          overflow: "hidden",
          bgcolor: isDark ? "#101828" : "#ffffff",
          backgroundImage: "none",
          display: "flex",
          flexDirection: "column",
        },
      }}
    >
      {decision ? (
        <UpdateProgressReportDecisionDrawerContent
          key={decision.id}
          decision={decision}
          onClose={onClose}
          onSave={onSave}
          readOnly={readOnly}
          onAddComment={onAddComment}
          decisionAttachment={decisionAttachment}
        />
      ) : null}
    </Drawer>
  );
}
