import { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";

import DelegationForm from "@/record-management/components/delegation/delegationForm";

import { useLocation, useNavigate, useParams } from "react-router-dom";
import { useDelegations } from "@/record-management/components/hooks/useDelegations";
import { editdelegationFormSchema } from "./delegationFormSchema";
import { toast } from "sonner";
import { useSignatureListWithPresigned } from "../hooks/useSignatureAndTeeterWithPresigned";
import { useAuthUser } from "@/record-management/hooks/useAuthUser";
import useSettings from "../hooks/useSettings";
import { DelegatePositionDto } from "@/record-management/dto/delegation/delegationDto";
import { useTranslation } from "react-i18next";
import {
  fetchRecordContentByRecordId,
  RecordContentOutgoingHistory,
} from "@/record-management/services/api/userRecordService";

type DelegationFormValues = z.infer<typeof editdelegationFormSchema>;

const EditDelegationPage = () => {
  const { id } = useParams<{ id: string }>();
  const location = useLocation();
  const navigate = useNavigate();
  const baseParams = {
    skip: 0,
    take: 200,
    orderBy: "employeePosition.createdAt:DESC",
  };
  const { editDelegation, delegations, refetch } = useDelegations(baseParams);
  const { userDetails } = useAuthUser();
  const employeeId = userDetails?.employee?.[0]?.id ?? "";
  const { data: signatureData } = useSignatureListWithPresigned(employeeId);
  const { allDepartmentUnits } = useSettings();
  const { t } = useTranslation();
  const routeDelegation = (
    location.state as { delegation?: DelegatePositionDto } | null
  )?.delegation;
  const fetchedDelegation = delegations?.data?.find((e) => e.id === id);
  const delegation =
    routeDelegation?.id === id ? routeDelegation : fetchedDelegation;
  const [resolvedInternalCC, setResolvedInternalCC] = useState<string[]>([]);
  const [latestOutgoingHistory, setLatestOutgoingHistory] =
    useState<RecordContentOutgoingHistory | null>(null);

  const StartDate = delegation?.startDate;
  const ParsedStartDate = useMemo(
    () => (delegation?.startDate ? new Date(delegation.startDate) : null),
    [delegation?.startDate],
  );
  const EndDate = useMemo(
    () => (delegation?.endDate ? new Date(delegation.endDate) : null),
    [delegation?.endDate],
  );
  const internalCC = delegation?.internalCC;
  const stampId = delegation?.stampId;
  const AmharicStartDate = delegation?.amharicStartDate;
  const AmharicEndDate = delegation?.amharicEndDate;
  const delegationEmployeePosition = (delegation as any)?.employeePosition;
  const selectedEmployeeId =
    delegation?.employeePositionId ||
    delegationEmployeePosition?.id ||
    delegation?.employee?.employeePositions?.find(
      (employeePosition: any) =>
        employeePosition?.position?.id === delegation?.delegateePosition?.id,
    )?.id ||
    delegation?.employee?.employeePositions?.[0]?.id ||
    delegation?.employee?.id ||
    "";
  const form = useForm<DelegationFormValues>({
    resolver: zodResolver(editdelegationFormSchema),
    defaultValues: {
      positionId: delegation?.positionId || "",
      employeeId: selectedEmployeeId,
      startDate: ParsedStartDate || new Date(),
      endDate: EndDate || new Date(),
      internalCC: resolvedInternalCC || internalCC || [],
      stampId: stampId || "",
      language: delegation?.delegationLetter?.preferredLanguage || "am",
    },
  });

  useEffect(() => {
    if (!delegation) return;

    form.setValue("positionId", delegation.delegateePosition?.id || "", {
      shouldDirty: false,
    });
    form.setValue("employeeId", selectedEmployeeId, {
      shouldDirty: false,
    });
    form.setValue("startDate", ParsedStartDate || new Date(), {
      shouldDirty: false,
    });
    form.setValue("endDate", EndDate || new Date(), {
      shouldDirty: false,
    });
    form.setValue("stampId", stampId || "", {
      shouldDirty: false,
    });
    form.setValue(
      "language",
      delegation?.delegationLetter?.preferredLanguage || "am",
      {
        shouldDirty: false,
      },
    );
  }, [delegation, form, ParsedStartDate, EndDate, stampId, selectedEmployeeId]);

  useEffect(() => {
    const letterId =
      delegation?.delegationLetter?.id || delegation?.delegationLetterId?.id;

    if (!letterId) {
      const fallbackInternalCC = internalCC || [];
      setLatestOutgoingHistory(null);
      setResolvedInternalCC(fallbackInternalCC);
      form.setValue("internalCC", fallbackInternalCC, {
        shouldDirty: false,
      });
      return;
    }

    const loadDelegationInternalCC = async () => {
      try {
        const recordContent = await fetchRecordContentByRecordId(letterId);
        const topOutgoingHistory =
          recordContent?.outgoingHistories?.[0] ?? null;
        const nextInternalCC = (recordContent?.ccPositions ?? [])
          .map((cc: any) => cc?.position?.id)
          .filter((ccId: unknown): ccId is string => typeof ccId === "string");

        const fallbackInternalCC = internalCC || [];
        const resolved =
          nextInternalCC.length > 0 ? nextInternalCC : fallbackInternalCC;
        setLatestOutgoingHistory(topOutgoingHistory);
        setResolvedInternalCC(resolved);
        form.setValue("internalCC", resolved, {
          shouldDirty: false,
        });
      } catch {
        const fallbackInternalCC = internalCC || [];
        setLatestOutgoingHistory(null);
        setResolvedInternalCC(fallbackInternalCC);
        form.setValue("internalCC", fallbackInternalCC, {
          shouldDirty: false,
        });
      }
    };

    loadDelegationInternalCC();
  }, [delegation, form, internalCC]);

  const handleEditDelegation = (values: DelegationFormValues) => {
    const departmentUnitByValue = new Map(
      allDepartmentUnits.map((unit) => [
        unit.id && unit.id.trim() !== "" ? unit.id : unit.key || "",
        unit,
      ]),
    );
    const internalCCValues =
      values.internalCC
        ?.map((selectedId) => departmentUnitByValue.get(selectedId))
        .filter((unit): unit is (typeof allDepartmentUnits)[number] =>
          Boolean(unit),
        ) ?? [];
    editDelegation(
      {
        ...values,
        id: delegation?.delegationLetter?.id || "",
        startDate: values.startDate,
        endDate: values.endDate,
        positionId: values.positionId,
        employeeId: values.employeeId,
        // Reverse so the BE's render-time reversal lands back on selection
        // order — mirrors the workaround applied in add/edit user records.
        internalCC: [
          ...(internalCCValues?.slice().map((c) => ({
            unitId: c.unitId!,
            positionId: c.id!,
            type: "internal" as const,
          })) ?? []),
        ],
        stampId: values.stampId,
        signatureId:
          signatureData?.items?.find(
            (item) => item.isCurrent && item.uploadedSuccessfully,
          )?.id || "",
        language: values.language ?? "am",
      },
      {
        onSuccess: () => {
          navigate("/record-management/delegation");
          toast.success(t("delegation.updatedSuccess"));
          refetch();
        },
      },
    );
  };

  return (
    <DelegationForm
      formInstance={form}
      onSubmit={handleEditDelegation}
      isEditing={true}
      selectedPositionId={delegation?.delegateePosition?.id || ""}
      selectedPositionName={delegation?.delegateePosition?.name}
      selectedEmployeeId={selectedEmployeeId}
      startDate={StartDate}
      endDate={EndDate}
      startAmDate={AmharicStartDate}
      endAmDate={AmharicEndDate}
      internalCC={resolvedInternalCC}
      stampId={stampId || ""}
      latestOutgoingHistory={latestOutgoingHistory ?? undefined}
    />
  );
};

export default EditDelegationPage;
