import { useEffect, useState } from "react";
import Cookies from "js-cookie";
import { useForm, type Resolver } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Input } from "@/shared/common/ui/input";
import { Button } from "@/shared/common/ui/button";
import {
  Form,
  FormField,
  FormItem,
  FormLabel,
  FormControl,
  FormMessage,
} from "@/shared/common/ui/form";
import { ReusableFileUploader } from "@/shared/common/ui/fileUploader/reusableFileUploader";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import {
  createLetterSchema,
  createComplaintLetterSchema,
  defaultCreateLetterValues,
  defaultCreateComplaintLetterValues,
  CreateLetterFormValues,
} from "./formSchema";
import { useExternalPortal } from "@/external-portal/hooks/useCreateExternalLetterRecord";
import { useNavigate } from "react-router-dom";
import { recordFileService } from "@/record-management/services/api/recordFileService";
import { RadioGroup, RadioGroupItem } from "@/shared/common/ui/radio-group";
import { Label } from "@/shared/common/ui/label";
import { motion } from "framer-motion";
import { useUser } from "@/shared/context/UserContext";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import { Textarea } from "@/shared/common/ui/textarea";
import { ComplaintVerifiedInfoPanel } from "@/complaints/components/ComplaintVerifiedInfoPanel";
import {
  clearComplaintVerification,
  getComplaintVerification,
} from "@/complaints/utils/complaintVerificationStorage";
import { COMPLAINT_RECORDS_PATH } from "@/complaints/utils/complaintRoutes";
import {
  unitConfigurationService,
  type CanReceiveComplaintResponse,
} from "@/shared/services/unitConfigurationService";
import {
  getExternalPortalReceivingUnitName,
  resolveExternalPortalReceivingUnitIds,
} from "@/external-portal/config/receivingOrganization";
import {
  PortalFieldLabel,
  PortalFormHeader,
  PortalFormSection,
  PortalReadOnlyField,
} from "../shared/PortalFormPrimitives";
import { ArrowLeft, Building2, Send } from "lucide-react";

interface AddIncomingRecordPortalFormProps {
  onSuccess?: () => void;
  onCancel?: () => void;
}

const SubmitExternalRecordForm = ({
  onSuccess,
  onCancel,
}: AddIncomingRecordPortalFormProps) => {
  const { t, i18n } = useTranslation();
  const complaintSession = getComplaintVerification();
  const isComplaintMode = complaintSession !== null;
  const hasAuthToken = Boolean(Cookies.get("auth-token"));

  const [canReceiveComplaintConfig, setCanReceiveComplaintConfig] =
    useState<CanReceiveComplaintResponse | null>(null);
  const [isLoadingCanReceiveComplaintConfig, setIsLoadingCanReceiveComplaintConfig] =
    useState(false);

  type FormValues = CreateLetterFormValues & {
    description?: string;
    recipient?: string;
  };

  const form = useForm<FormValues>({
    resolver: zodResolver(
      (isComplaintMode
        ? createComplaintLetterSchema
        : createLetterSchema) as typeof createLetterSchema,
    ) as Resolver<FormValues>,
    defaultValues: (isComplaintMode
      ? defaultCreateComplaintLetterValues
      : defaultCreateLetterValues) as FormValues,
    mode: "onChange",
  });

  const [showRegistrationAlert, setShowRegistrationAlert] = useState(false);
  const userDetails = useUser();
  const { handleError } = useErrorHandler(t);
  const hasCompletedRegistration = userDetails?.hasFinishedRegistration;
  const { createExternalPortalLetter, isSending } = useExternalPortal();
  const [files, setFiles] = useState<File[]>([]);
  const [mainFileIndex, setMainFileIndex] = useState<number | null>(null);
  const navigate = useNavigate();
  const handleCancel = onCancel ?? (() => navigate(COMPLAINT_RECORDS_PATH));
  const complaintReceivingUnitId = resolveExternalPortalReceivingUnitIds()[0];
  const receivingOrganizationName = getExternalPortalReceivingUnitName(
    i18n.language,
  );

  useEffect(() => {
    if (!hasCompletedRegistration && !isComplaintMode) {
      setShowRegistrationAlert(true);
    } else {
      setShowRegistrationAlert(false);
    }
  }, [hasCompletedRegistration, isComplaintMode]);

  // Complaint receiving unit is the configured target unit (not the submitter's unit).
  useEffect(() => {
    if (!isComplaintMode) return;
    if (!hasAuthToken) return;
    if (!complaintReceivingUnitId) return;

    let isCancelled = false;
    const load = async () => {
      try {
        setIsLoadingCanReceiveComplaintConfig(true);
        const res = await unitConfigurationService.getCanReceiveComplaint(
          complaintReceivingUnitId,
        );

        if (isCancelled) return;
        setCanReceiveComplaintConfig(res.data);
      } catch (err) {
        if (isCancelled) return;
        setCanReceiveComplaintConfig(null);
        toast.error(
          t(
            "complaint.receiveCheckFailed",
            "Could not verify complaint receiving for this unit. Please try again.",
          ),
        );
      } finally {
        if (!isCancelled) {
          setIsLoadingCanReceiveComplaintConfig(false);
        }
      }
    };

    load();
    return () => {
      isCancelled = true;
    };
  }, [complaintReceivingUnitId, hasAuthToken, isComplaintMode, t]);

  useEffect(() => {
    if (!isComplaintMode) return;
    if (!hasAuthToken) return;
    if (!canReceiveComplaintConfig) return;

    if (canReceiveComplaintConfig.canReceiveComplaint === false) {
      toast.error(
        t(
          "complaint.receiveDisabled",
          "Complaint receiving is disabled for this unit.",
        ),
      );
      navigate(COMPLAINT_RECORDS_PATH);
    }
  }, [
    canReceiveComplaintConfig,
    hasAuthToken,
    isComplaintMode,
    navigate,
    t,
  ]);

  useEffect(() => {
    if (files.length === 1) {
      setMainFileIndex(0);
    }
  }, [files]);

  const buildComplaintSubject = (
    subject: string,
    recipient?: string,
    description?: string,
  ) => {
    let composed = subject.trim();
    if (recipient?.trim()) {
      composed = `[To: ${recipient.trim()}] ${composed}`;
    }
    if (description?.trim()) {
      composed = `${composed}\n\n${description.trim()}`;
    }
    return composed;
  };

  const isAllowedMainFile = (file: File) => {
    if (!isComplaintMode) {
      return file.type === "application/pdf";
    }
    return (
      file.type === "application/pdf" ||
      file.type === "image/jpeg" ||
      file.type === "image/png"
    );
  };

  const onSubmit = async (values: FormValues) => {
    if (files.length === 0) {
      toast.error(t("userRecord.Please select file"));
      return;
    }

    if (mainFileIndex === null) {
      toast.error(t("Please select the main file for the record"));
      return;
    }

    const mainFile = files[mainFileIndex];
    const fileInfo = {
      fileName: mainFile.name,
      contentType: mainFile.type,
      size: mainFile.size,
      originalname: mainFile.name,
    };

    const unitIds = isComplaintMode
      ? [complaintReceivingUnitId]
      : resolveExternalPortalReceivingUnitIds();

    if (isComplaintMode) {
      if (isLoadingCanReceiveComplaintConfig) {
        toast.error(
          t(
            "complaint.receiveCheckInProgress",
            "Still verifying complaint receiving for this unit. Please wait.",
          ),
        );
        return;
      }

      if (!canReceiveComplaintConfig) {
        toast.error(
          t(
            "complaint.receiveCheckFailed",
            "Could not verify complaint receiving for this unit. Please try again.",
          ),
        );
        return;
      }

      if (canReceiveComplaintConfig.canReceiveComplaint === false) {
        toast.error(
          t(
            "complaint.receiveDisabled",
            "Complaint receiving is disabled for this unit.",
          ),
        );
        return;
      }
    }

    if (!complaintReceivingUnitId && isComplaintMode) {
      toast.error(
        t(
          "complaint.receiveCheckFailed",
          "Could not verify complaint receiving for this unit. Please try again.",
        ),
      );
      return;
    }

    if (!isAllowedMainFile(mainFile)) {
      toast.error(
        isComplaintMode
          ? t("complaint.fayda.uploadHint")
          : t("userRecord.The main file must be a PDF document"),
      );
      return;
    }

    const letterNumber =
      values.letterNumber?.trim() ||
      (isComplaintMode ? `CMP-${Date.now()}` : "");

    if (!letterNumber) {
      toast.error(t("userRecord.Letter Number"));
      return;
    }

    const subject = isComplaintMode
      ? buildComplaintSubject(
          values.subject,
          values.recipient,
          values.description,
        )
      : values.subject;

    try {
      const recordResult = await createExternalPortalLetter(
        {
          ...values,
          subject,
          fileInfo,
          unitIds,
          letterNumber,
        },
        mainFile,
      );
      const contentId = recordResult.contentId;

      if (!contentId) {
        throw new Error("Missing contentId from created record");
      }

      form.reset();
      setFiles([]);
      setMainFileIndex(null);

      const attachments = files.filter((_, idx) => idx !== mainFileIndex);
      if (attachments.length > 0) {
        try {
          await Promise.all(
            attachments.map(async (attachment) => {
              const uploadMetaResult = await recordFileService.uploadMeta(
                attachment,
                attachment.name,
                contentId,
              );

              await recordFileService.uploadFile(
                attachment,
                uploadMetaResult.presigned,
              );
              await recordFileService.updateStatus(
                uploadMetaResult.id,
                contentId,
                true,
              );
            }),
          );
        } catch (error: unknown) {
          handleError(error);
        }
      }

      toast.success(
        isComplaintMode
          ? t("complaint.success")
          : t("externalPortal.letterSentSuccess"),
      );
      if (isComplaintMode) {
        clearComplaintVerification();
      }
      onSuccess?.();
      navigate(COMPLAINT_RECORDS_PATH);
    } catch (error) {
      await handleError(error);
    }
  };

  const handleGoToDocuments = () => {
    navigate("/external-portal/upload-documents");
    setShowRegistrationAlert(false);
  };

  return (
    <>
      {showRegistrationAlert && (
        <motion.div
          initial={{ opacity: 0, y: -20 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: -20 }}
          className="bg-yellow-50 border-l-4 border-yellow-400 p-4">
          <div className="flex items-center justify-between max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div className="flex items-start">
              <div className="flex-shrink-0">
                <svg
                  className="h-5 w-5 text-yellow-400"
                  xmlns="http://www.w3.org/2000/svg"
                  viewBox="0 0 20 20"
                  fill="currentColor">
                  <path
                    fillRule="evenodd"
                    d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
                    clipRule="evenodd"
                  />
                </svg>
              </div>
              <div className="ml-3">
                <p className="text-sm text-yellow-700">
                  You haven't completed the verification process. Please upload
                  required documents to continue.
                </p>
              </div>
            </div>
            <div className="ml-4 flex-shrink-0">
              <button
                onClick={handleGoToDocuments}
                className="inline-flex items-center px-3 py-1.5 border border-transparent text-xs font-medium rounded-md shadow-sm text-white bg-yellow-600 hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500">
                Upload Documents
              </button>
            </div>
          </div>
        </motion.div>
      )}
      <Form {...form}>
        <form
          onSubmit={form.handleSubmit(onSubmit)}
          className="space-y-6"
          aria-labelledby="form-title">
          {isComplaintMode ? (
            <button
              type="button"
              onClick={() => navigate(COMPLAINT_RECORDS_PATH)}
              className="inline-flex items-center gap-2 text-sm font-medium text-slate-600 transition-colors hover:text-primary"
            >
              <ArrowLeft className="h-4 w-4" />
              {t("complaint.fayda.backToMyRecords")}
            </button>
          ) : null}

          <PortalFormHeader
            title={
              isComplaintMode
                ? t("complaint.formTitle")
                : t("userIncoming.uploadIncomingRecord")
            }
            subtitle={
              isComplaintMode ? t("complaint.fayda.formSubtitle") : undefined
            }
          />

          {complaintSession ? (
            <ComplaintVerifiedInfoPanel session={complaintSession} />
          ) : null}

          <PortalFormSection className="w-full min-w-0 max-w-full space-y-5 overflow-visible">
            {!isComplaintMode ? (
              <PortalReadOnlyField
                label={t("userIncoming.Receiving Organization")}
                value={receivingOrganizationName}
                icon={Building2}
              />
            ) : null}

            <FormField
              control={form.control}
              name="subject"
              render={({ field }) => (
                <FormItem>
                  <FormLabel asChild>
                    <PortalFieldLabel required>
                      {t("userIncoming.Subject")}
                    </PortalFieldLabel>
                  </FormLabel>
                  <FormControl>
                    <Input
                      placeholder={t("userIncoming.Subject")}
                      className="h-11 rounded-lg border-slate-200 focus-visible:ring-primary/20"
                      {...field}
                      disabled={isSending}
                      aria-required="true"
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            {isComplaintMode ? (
              <FormField
                control={form.control}
                name="description"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel asChild>
                      <PortalFieldLabel required>
                        {t("complaint.fayda.description")}
                      </PortalFieldLabel>
                    </FormLabel>
                    <FormControl>
                      <Textarea
                        placeholder={t(
                          "complaint.fayda.descriptionPlaceholder",
                        )}
                        className="min-h-[160px] resize-none rounded-lg border-slate-200 focus-visible:ring-primary/20"
                        {...field}
                        disabled={isSending}
                        aria-required="true"
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            ) : null}

            {!isComplaintMode ? (
              <FormField
                control={form.control}
                name="letterNumber"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel asChild>
                      <PortalFieldLabel required>
                        {t("userRecord.Letter Number")}
                      </PortalFieldLabel>
                    </FormLabel>
                    <FormControl>
                      <Input
                        placeholder={t("userRecord.Letter Number")}
                        className="h-11 rounded-lg border-slate-200 focus-visible:ring-primary/20"
                        {...field}
                        disabled={isSending}
                        aria-required="true"
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            ) : null}

            <div>
              <PortalFieldLabel required>
                {isComplaintMode
                  ? t("complaint.fayda.attachment")
                  : t("userIncoming.Attachments")}
              </PortalFieldLabel>
              <div className="mt-2 rounded-xl border-2 border-dashed border-slate-200 bg-slate-50/50 p-2 transition-colors hover:border-primary/40">
                <ReusableFileUploader
                  files={files}
                  setFiles={setFiles}
                  isLoading={isSending}
                />
              </div>
            </div>

            {files.length > 0 && (
              <div>
                <PortalFieldLabel required>
                  {t("Select the main file for the record")}
                </PortalFieldLabel>
                <RadioGroup
                  className="mt-2"
                  value={mainFileIndex?.toString() || ""}
                  onValueChange={(value) => setMainFileIndex(Number(value))}
                  aria-required="true">
                  {files.map((file, index) => (
                    <div key={file.name} className="flex items-center space-x-2">
                      <RadioGroupItem
                        value={index.toString()}
                        id={`main-file-${index}`}
                      />
                      <Label htmlFor={`main-file-${index}`}>{file.name}</Label>
                    </div>
                  ))}
                </RadioGroup>
              </div>
            )}
          </PortalFormSection>

          <div className="flex flex-col-reverse gap-3 pt-2 sm:flex-row sm:items-center sm:justify-between">
            <p className="text-xs text-slate-500">{t("common.requiredFields")}</p>
            <div className="flex w-full flex-col gap-3 sm:w-auto sm:flex-row">
              <Button
                type="button"
                variant="outline"
                onClick={handleCancel}
                disabled={isSending}
                className="h-11 min-w-[8rem] rounded-lg">
                {t("common.Cancel")}
              </Button>
              <Button
                type="submit"
                disabled={
                  !form.formState.isValid ||
                  isSending ||
                  files.length === 0 ||
                  (isComplaintMode &&
                    (isLoadingCanReceiveComplaintConfig ||
                      canReceiveComplaintConfig?.canReceiveComplaint !== true))
                }
                className="h-11 min-w-[10rem] rounded-lg bg-primary hover:bg-primary/90">
                {isSending ? (
                  t("userIncoming.Processing...")
                ) : (
                  <span className="inline-flex items-center gap-2">
                    {isComplaintMode ? t("complaint.submit") : t("common.Submit")}
                    {isComplaintMode ? <Send className="h-4 w-4" /> : null}
                  </span>
                )}
              </Button>
            </div>
          </div>
        </form>
      </Form>
    </>
  );
};

export default SubmitExternalRecordForm;
