import React, { useEffect, useRef, useState } from "react";
import { useForm, Controller, type FieldErrors } from "react-hook-form";
import { toast } from "sonner";
import { Button } from "@/shared/common/ui/button";
import { useTranslation } from "react-i18next";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/common/ui/select";
import { Textarea } from "@/shared/common/ui/textarea";

import { useAuthUser } from "@/shared/hooks/useAuthUser";

import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/shared/common/ui/dialog";
import { UploadedTeeter } from "../Settings/uploadTeeterandSingature";
import { useApprovalTasks } from "../hooks/useApprovalTasks";
import {
  useSignatureListWithPresigned,
  useTeetersListWithPresigned,
} from "../hooks/useSignatureAndTeeterWithPresigned";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import { usePositionPrefixes } from "../hooks/usePositionPrefixes";
import { useUnitConfiguration } from "@/shared/hooks/useUnitConfiguration";
import { getNoStampsForLanguageMessage } from "@/record-management/utils/stampMessages";

export interface ApprovalSubmitData {
  stampId?: string;
  signatureId?: string;
  note: string;
  recordPrefixId?: string;
}

interface ApproveRecordProps {
  open: boolean;
  onClose: () => void;
  /** Required for the default flow. Optional when `onCustomSubmit` is provided
   *  (e.g. "Create and Approve" where the record doesn't exist yet). */
  recordId?: string;
  onSuccess: () => void;
  recordData?: {
    unitId: string;
    recordTypeKey: string;
    referenceNumber?: string;
  };
  preferredLanguage?: string;
  /** When provided, the modal calls this with the collected approval data
   *  instead of running the default `submitAndSend`. Use this to drive
   *  combined endpoints like create-submit-and-send-to-ro or
   *  update-submit-and-send-to-ro. */
  onCustomSubmit?: (data: ApprovalSubmitData) => Promise<void>;
}

type ApproveFormValues = {
  reason: string;
  selectedTeeter: string;
  selectedSignature: string;
  selectedPositionPrefix?: string;
};

interface UploadedSignature {
  id: string;
  url: string;
}

type LocalizedNameValue = {
  en?: string;
  am?: string;
};

const ApproveRecordModal: React.FC<ApproveRecordProps> = ({
  open,
  onClose,
  recordId,
  onSuccess,
  recordData,
  onCustomSubmit,
  preferredLanguage,
}) => {
  const { submitAndSend, isSubmitAndSendLoading, refetch } = useApprovalTasks();
  const { t, i18n } = useTranslation();
  const [uploadedTeeters, setUploadedTeeters] = useState<UploadedTeeter[]>([]);
  const [signatures, setSignatures] = useState<UploadedSignature[]>([]);
  const [defaultSignature, setDefaultSignature] = useState<
    string | undefined
  >();
  const [selectedTeeterUrl, setSelectedTeeterUrl] = useState<string>("");
  const [selectedSignatureUrl, setSelectedSignatureUrl] = useState<string>("");
  const teeterRef = useRef<HTMLDivElement>(null);
  const positionPrefixRef = useRef<HTMLDivElement>(null);
  const { control, handleSubmit, reset, setValue, watch } =
    useForm<ApproveFormValues>({
      defaultValues: {
        reason: "",
        selectedTeeter: "",
        selectedSignature: "",
        selectedPositionPrefix: "",
      },
    });

  const selectedTeeter = watch("selectedTeeter");
  const selectedSignature = watch("selectedSignature");

  const { userDetails } = useAuthUser();
  const unitId = userDetails?.employee?.[0]?.unitId ?? "";

  const employeeId = userDetails?.employee?.[0]?.id ?? "";
  const approverPositionId =
    userDetails?.employee?.[0]?.positions?.[0]?.id ?? undefined;

  const { data: signatureData } = useSignatureListWithPresigned(employeeId);
  const locale: "am" | "en" = (preferredLanguage ?? "")
    .toLowerCase()
    .startsWith("am")
    ? "am"
    : "en";
  const { data: teeterData } = useTeetersListWithPresigned(locale);
  const { handleError } = useErrorHandler(t);
  const { data: unitConfigData } = useUnitConfiguration(unitId, {
    enabled: !!unitId,
  });
  const canPositionBasedReferenceBeUsedForAllTypes =
    unitConfigData?.data?.items?.[0]
      ?.canPositionBasedReferenceBeUsedForAllTypes ?? false;
  const canInternalMemoRequirePositionBasedReferenceNumber =
    unitConfigData?.data?.items?.[0]
      ?.canInternalMemoRequirePositionBasedReferenceNumber ?? false;
  const hasReferenceNumber = Boolean(recordData?.referenceNumber?.trim());

  // Fetch position prefixes if record data is available, filtered by approver's position and record type
  const { data: positionPrefixes = [] } = usePositionPrefixes(
    unitId || "",
    recordData?.recordTypeKey || "external",
    approverPositionId,
  );
  const shouldShowPositionPrefixSelector =
    !hasReferenceNumber &&
    (canPositionBasedReferenceBeUsedForAllTypes ||
      recordData?.recordTypeKey === "internal_memo");
  const isInternalMemoRecord = recordData?.recordTypeKey === "internal_memo";

  const isPositionPrefixRequired =
    !hasReferenceNumber &&
    isInternalMemoRecord &&
    canInternalMemoRequirePositionBasedReferenceNumber;
  const effectivePreferredLanguage =
    preferredLanguage === "am" || preferredLanguage === "en"
      ? preferredLanguage
      : preferredLanguage?.toLowerCase().startsWith("am")
        ? "am"
        : preferredLanguage?.toLowerCase().startsWith("en")
          ? "en"
          : i18n.language?.startsWith("am")
            ? "am"
            : "en";

  const localizedValue = (name: { en: string; am: string }) => {
    if (effectivePreferredLanguage === "am") {
      return name.am || name.en;
    }
    return name.en || name.am;
  };
  useEffect(() => {
    const teeters = teeterData?.presignedTeeters;
    if (teeters?.length) {
      setUploadedTeeters(teeters);
      const match =
        teeters.find((t) => t.locale === locale) ??
        (teeters.length === 1 ? teeters[0] : null);
      if (match) {
        setValue("selectedTeeter", match.id);
        setSelectedTeeterUrl(match.url);
      }
    }

    const currentItem = signatureData?.items.find(
      (item) => item.isCurrent && item.uploadedSuccessfully,
    );

    if (currentItem && signatureData?.presignedSignatureUrl) {
      const validSignatures = [
        {
          id: currentItem.id,
          url: signatureData.presignedSignatureUrl,
          name: currentItem.fileInfo.originalname,
        },
      ];

      setSignatures(validSignatures);
      setDefaultSignature(currentItem.id);
      setValue("selectedSignature", currentItem.id);
      setSelectedSignatureUrl(signatureData.presignedSignatureUrl);
    }
  }, [teeterData, signatureData, setValue, locale]);

  useEffect(() => {
    if (selectedTeeter) {
      const teeter = uploadedTeeters.find((t) => t.id === selectedTeeter);
      setSelectedTeeterUrl(teeter?.url || "");
    }
  }, [selectedTeeter, uploadedTeeters]);

  useEffect(() => {
    if (selectedSignature) {
      const signature = signatures.find((s) => s.id === selectedSignature);
      setSelectedSignatureUrl(signature?.url || "");
    }
  }, [selectedSignature, signatures]);

  useEffect(() => {
    if (!shouldShowPositionPrefixSelector) {
      setValue("selectedPositionPrefix", "");
    }
  }, [setValue, shouldShowPositionPrefixSelector]);
  const onError = (errors: FieldErrors<ApproveFormValues>) => {
    if (errors.selectedTeeter) {
      teeterRef.current?.scrollIntoView({
        behavior: "smooth",
        block: "center",
      });
      return;
    }

    if (errors.selectedPositionPrefix) {
      positionPrefixRef.current?.scrollIntoView({
        behavior: "smooth",
        block: "center",
      });
    }
  };
  const onSubmit = async (data: ApproveFormValues) => {
    if (!data.selectedTeeter) {
      toast.error(t("ApprovalPage.selectStamp"));
      return;
    }

    if (isPositionPrefixRequired && !data.selectedPositionPrefix) {
      toast.error(
        t(
          "ApprovalPage.positionPrefixRequired",
          "Reference number selection is required",
        ),
      );
      return;
    }

    const approvalPayload: ApprovalSubmitData = {
      stampId: data.selectedTeeter || undefined,
      signatureId: data.selectedSignature || defaultSignature,
      note: data.reason ? data.reason : "No Comment/አስተያየት የለም",
      recordPrefixId: data.selectedPositionPrefix
        ? data.selectedPositionPrefix
        : undefined,
    };

    try {
      if (onCustomSubmit) {
        await onCustomSubmit(approvalPayload);
      } else {
        if (!recordId) {
          toast.error("Invalid record ID");
          return;
        }
        await Promise.all([
          submitAndSend({
            id: recordId,
            ...approvalPayload,
          }),
          refetch(),
        ]);
      }
      toast.success(t("ApprovalPage.recordApprovedSuccessfully"));
      onSuccess();
      handleClose();
    } catch (error) {
      handleError(error);
    }
  };

  const handleClose = () => {
    reset();
    setSelectedTeeterUrl("");
    setSelectedSignatureUrl("");
    onClose();
  };

  return (
    <Dialog
      open={open}
      onOpenChange={(nextOpen) => {
        if (!nextOpen) {
          handleClose();
        }
      }}
    >
      <DialogContent
        className="w-[calc(100vw-2rem)] max-w-[425px] max-h-[85vh] overflow-hidden p-0 sm:max-w-[425px]"
        onEscapeKeyDown={(event) => event.preventDefault()}
        onPointerDownOutside={(event) => event.preventDefault()}
      >
        <DialogHeader className="border-b px-6 pb-4 pt-6">
          <DialogTitle>{t("ApprovalPage.approveRecord")}</DialogTitle>
        </DialogHeader>

        <form
          onSubmit={handleSubmit(onSubmit, onError)}
          className="flex max-h-[calc(85vh-4.5rem)] flex-col"
        >
          <div className="flex-1 space-y-4 overflow-y-auto px-6 py-4">
            <div ref={teeterRef}>
              <label className="block text-sm font-medium">
                {t("ApprovalPage.selectStamp")}
              </label>
              {uploadedTeeters.length === 0 ? (
                teeterData ? (
                  <p className="mt-2 rounded border border-amber-200 bg-amber-50 p-2 text-sm text-amber-700 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-300">
                    {getNoStampsForLanguageMessage(locale, t)}
                  </p>
                ) : (
                  <p className="mt-2 text-sm text-muted-foreground">
                    {t("common.loading")}
                  </p>
                )
              ) : uploadedTeeters.length === 1 ? (
                <div className="mt-2 border rounded p-2">
                  <p className="text-sm font-medium mb-1">
                    {t("ApprovalPage.yourStamp")}
                  </p>
                  <div className="relative h-24 w-24">
                    {selectedTeeterUrl && (
                      <img
                        src={selectedTeeterUrl}
                        alt="Your stamp"
                        className="h-24 w-24 object-contain"
                      />
                    )}
                  </div>
                </div>
              ) : (
                <Controller
                  name="selectedTeeter"
                  control={control}
                  rules={{ required: "Please select a stamp" }}
                  render={({ field, fieldState }) => (
                    <>
                      <Select
                        onValueChange={field.onChange}
                        value={field.value}
                      >
                        <SelectTrigger>
                          <SelectValue
                            placeholder={t("ApprovalPage.selectStamp")}
                          >
                            {field.value
                              ? (teeterData?.presignedTeeters?.find(
                                  (t) => t.id === field.value,
                                )?.name ?? t("ApprovalPage.selectStamp"))
                              : null}
                          </SelectValue>
                        </SelectTrigger>
                        <SelectContent>
                          {uploadedTeeters.map((teeter) => (
                            <SelectItem key={teeter.id} value={teeter.id}>
                              {(() => {
                                const name = teeter.name as unknown;
                                if (typeof name === "string") return name;
                                const localized = name as
                                  | LocalizedNameValue
                                  | undefined;
                                return (
                                  localized?.en || localized?.am || "Teeter"
                                );
                              })()}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      {fieldState.error && (
                        <p className="text-sm text-red-500 mt-1">
                          {fieldState.error.message}
                        </p>
                      )}
                      {selectedTeeterUrl && (
                        <div className="mt-2 border rounded p-2">
                          <p className="text-sm font-medium mb-1">
                            {t("ApprovalPage.selectedStamp")}
                          </p>
                          <div className="relative h-24 w-24">
                            <img
                              src={selectedTeeterUrl}
                              alt="Selected stamp"
                              className="h-24 w-24 object-contain"
                            />
                          </div>
                        </div>
                      )}
                    </>
                  )}
                />
              )}
            </div>

            {signatures.length > 0 && (
              <div>
                <label className="block text-sm font-medium">
                  {t("ApprovalPage.signature")}
                </label>
                {signatures.length === 1 ? (
                  <div className="mt-2 border rounded p-2">
                    <p className="text-sm font-medium mb-1">
                      {t("ApprovalPage.yourSignature")}
                    </p>
                    <div className="relative h-16 w-48">
                      {selectedSignatureUrl && (
                        <img
                          src={selectedSignatureUrl}
                          alt="Your signature"
                          className="h-24 w-24 object-contain"
                        />
                      )}
                    </div>
                  </div>
                ) : (
                  <Controller
                    name="selectedSignature"
                    control={control}
                    render={({ field }) => (
                      <>
                        <Select
                          onValueChange={field.onChange}
                          value={field.value}
                        >
                          <SelectTrigger>
                            <SelectValue placeholder="Select a signature" />
                          </SelectTrigger>
                          <SelectContent>
                            {signatures.map((signature) => (
                              <SelectItem
                                key={signature.id}
                                value={signature.id}
                              >
                                {t("ApprovalPage.signature")} {signature.id}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                        {selectedSignatureUrl && (
                          <div className="mt-2 border rounded p-2">
                            <p className="text-sm font-medium mb-1">
                              {t("ApprovalPage.selectedSignature")}
                            </p>
                            <div className="relative h-16 w-48">
                              <img
                                src={selectedSignatureUrl}
                                alt="Selected signature"
                                className="h-24 w-24 object-contain"
                              />
                            </div>
                          </div>
                        )}
                      </>
                    )}
                  />
                )}
              </div>
            )}

            {hasReferenceNumber && (
              <div>
                <label className="block text-sm font-medium">
                  {t("viewDetail.referenceNumber", "Reference Number")}
                </label>
                <div className="mt-1 rounded-md border bg-slate-50 px-3 py-2 text-sm font-medium text-slate-700">
                  {recordData?.referenceNumber}
                </div>
              </div>
            )}

            {shouldShowPositionPrefixSelector &&
              positionPrefixes.length > 0 && (
                <div ref={positionPrefixRef}>
                  {" "}
                  {/* Ref for scrolling into view on validation error */}
                  <label className="block text-sm font-medium">
                    {t("contentManagement.positionPrefixes") ||
                      "Position Prefix"}
                  </label>
                  <div className="flex gap-2 items-end">
                    <div className="flex-1">
                      <Controller
                        name="selectedPositionPrefix"
                        control={control}
                        rules={{
                          validate: (value) =>
                            !isPositionPrefixRequired ||
                            Boolean(value) ||
                            t(
                              "ApprovalPage.positionPrefixRequired",
                              "Reference number selection is required",
                            ),
                        }}
                        render={({ field, fieldState }) => (
                          <>
                            <Select
                              onValueChange={field.onChange}
                              value={field.value || ""}
                            >
                              <SelectTrigger>
                                <SelectValue
                                  placeholder={
                                    isInternalMemoRecord
                                      ? t(
                                          "addRecord.Select Position Prefix",
                                          "Select Position Prefix",
                                        )
                                      : t(
                                          "contentManagement.positionPrefixes",
                                        ) || "Select position prefix"
                                  }
                                />
                              </SelectTrigger>
                              <SelectContent>
                                {positionPrefixes.map((prefix) => (
                                  <SelectItem key={prefix.id} value={prefix.id}>
                                    {localizedValue(prefix.name)}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                            {fieldState.error ? (
                              <p className="mt-1 text-sm text-red-500">
                                {fieldState.error.message}
                              </p>
                            ) : (
                              isPositionPrefixRequired && (
                                <p className="mt-1 text-xs text-slate-500">
                                  {t(
                                    "ApprovalPage.positionPrefixRequired",
                                    "Reference number selection is required",
                                  )}
                                </p>
                              )
                            )}
                          </>
                        )}
                      />
                    </div>
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      onClick={() => setValue("selectedPositionPrefix", "")}
                      className="h-10 px-3"
                    >
                      {t("common.Cancel") || "Clear"}
                    </Button>
                  </div>
                </div>
              )}

            <div>
              <label className="block text-sm font-medium">
                {t("ApprovalPage.Remark")}
              </label>
              <Controller
                name="reason"
                control={control}
                render={({ field }) => (
                  <Textarea
                    {...field}
                    placeholder={t("ApprovalPage.Remark")}
                    rows={4}
                    className="w-full"
                  />
                )}
              />
            </div>
          </div>

          <div className="flex justify-end space-x-2 border-t px-6 py-4">
            <Button type="button" variant="outline" onClick={handleClose}>
              {t("common.Cancel")}
            </Button>
            <Button
              type="submit"
              disabled={isSubmitAndSendLoading}
              className="bg-primary-800 text-white"
            >
              {isSubmitAndSendLoading
                ? t("ApprovalPage.approving")
                : t("statusBar.Approve")}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
};

export default ApproveRecordModal;
