"use client";
import { useState, useEffect, use, useCallback } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useSearchParams, useRouter } from "next/navigation";
import Image from "next/image";
import Link from "next/link";

import { firstTimeHomeBuyerSchema, FirstTimeHomeBuyerFormData } from "./schema";
import { steps } from "./constants";
import Step1 from "./steps/Step1";
import Step2 from "./steps/Step2";
import Step3 from "./steps/Step3";
import Step4 from "./steps/Step4";
import Step5 from "./steps/Step5";
import PaginationStepper from "@/src/components/admin/PaginationStepper";
import { useCustomToast } from "@/src/hooks/web/useCustomToast";
import {
  saveFTHBApplication,
  getFTHBApplicationById,
  submitFTHBApplication,
  getAllCountries,
  getAllStatesByCountry,
  getAllCitiesByState,
  getFTHBApplicationDocuments,
  getDocumentsByService,
} from "@/src/services/web/services";

import UnauthorizedAccess from "@/src/components/web/UnauthorizedAccess";

import Button from "@/src/components/web/ui/Button";

export default function FirstTimeHomeBuyerForm() {
  const searchParams = useSearchParams();
  const router = useRouter();
  const isReadOnly = searchParams.get("mode") === "view";
  const applicationIdParam = searchParams.get("id");

  const [activeStep, setActiveStep] = useState(1);
  const [applicationId, setApplicationId] = useState<number | null>(
    applicationIdParam ? parseInt(applicationIdParam) : null,
  );
  const [loading, setLoading] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);

  const [countryOptions, setCountryOptions] = useState<
    { label: string; value: string }[]
  >([]);
  const { showToast } = useCustomToast();
  const [step5ValidateFn, setStep5ValidateFn] = useState<
    (() => boolean) | null
  >(null);

  const handleStep5Validate = useCallback((fn: () => boolean) => {
    setStep5ValidateFn(() => fn);
  }, []);

  useEffect(() => {
    getAllCountries()
      .then((res) => {
        const countries = res.data.data.map((country: any) => ({
          label: country.name,
          value: country.id.toString(),
        }));
        setCountryOptions(countries);
      })
      .catch((err) => console.error(err));
  }, []);

  const {
    control,
    handleSubmit,
    setValue,
    watch,
    trigger,
    setError,
    clearErrors,
    formState: { errors },
  } = useForm<FirstTimeHomeBuyerFormData>({
    resolver: zodResolver(firstTimeHomeBuyerSchema),
    mode: "onChange",
    defaultValues: {
      applicantName: "",
      coApplicantName: "",
      email: "",
      phoneCell: "",
      phoneWork: "",
      phoneHome: "",
      area: "",
      country: "",
      state: "",
      city: "",
      employerApplicant: "",
      employerCoApplicant: "",
      employerAddressCoApplicant: "",
      applicantHasIncome: "no",
      applicantIncomes: [],
      coApplicantHasIncome: "no",
      coApplicantIncomes: [],
      payees: [{ payeeName: "", amount: "" }],
      certificationSignature: "",
      certificationSignerName: "",
      certificationDateTime: "",
      authorizationSignature: "",
      authorizationSignerName: "",
      authorizationDateTime: "",
      authorizationCoApplicantSignature: "",
      authorizationCoApplicantSignerName: "",
      authorizationCoApplicantDateTime: "",
      inspectionSignature: "",
      inspectionSignerName: "",
      inspectionDateTime: "",
      inspectionCoApplicantSignature: "",
      inspectionCoApplicantSignerName: "",
      inspectionCoApplicantDateTime: "",
      bidApplicantSignature: "",
      bidApplicantSignerName: "",
      bidApplicantDateTime: "",
      bidCoApplicantSignature: "",
      bidCoApplicantSignerName: "",
      bidCoApplicantDateTime: "",
      notaryDay: "",
      notaryMonth: "",
      notaryYear: "",
      notaryAppearedName: "",
      documents: {},
    },
  });

  const watchCountry = watch("country");
  const watchState = watch("state");

  const [stateOptions, setStateOptions] = useState<
    { label: string; value: string }[]
  >([]);
  const [cityOptions, setCityOptions] = useState<
    { label: string; value: string }[]
  >([]);

  // Dynamic state and city options based on selection
  useEffect(() => {
    if (watchCountry) {
      getAllStatesByCountry(parseInt(watchCountry))
        .then((res) => {
          const states = res.data.data.map((state: any) => ({
            label: state.name,
            value: state.id.toString(),
          }));
          setStateOptions(states);
        })
        .catch((err) => console.error(err));
    } else {
      setStateOptions([]);
      setCityOptions([]);
    }
  }, [watchCountry]);

  useEffect(() => {
    if (watchState) {
      getAllCitiesByState(parseInt(watchState))
        .then((res) => {
          const cities = res.data.data.map((city: any) => ({
            label: city.name,
            value: city.id.toString(),
          }));
          setCityOptions(cities);
        })
        .catch((err) => console.error(err));
    } else {
      setCityOptions([]);
    }
  }, [watchState]);

  useEffect(() => {
    if (applicationId) {
      loadApplication();
    }
  }, []);

  const loadApplication = async () => {
    try {
      setLoading(true);
      setLoadError(null);
      const response = await getFTHBApplicationById(applicationId!);
      const data = response.data.data;
      const fthbData = data.fthbApplication;

      if (fthbData) {
        setValue("applicantName", data.applicant_name);
        setValue("coApplicantName", data.coapplicant_name || "");
        setValue("email", data.applicant_email);
        setValue("phoneCell", data.applicant_cellphone);
        setValue("phoneWork", data.applicant_workphone);
        setValue("phoneHome", data.applicant_homephone);
        setValue("area", data.applicant_area);
        setValue("country", data.applicant_country?.toString());
        setValue("state", data.applicant_state?.toString());
        setValue("city", data.applicant_city?.toString());
        setValue("isCurrentlyEmployed", fthbData.is_currently_employed || "no");
        setValue("employerApplicant", fthbData.applicant_employer_name);
        setValue("employerCoApplicant", fthbData.coapplicant_employer_name);
        setValue(
          "employerAddressCoApplicant",
          fthbData.coapplicant_employer_address,
        );
        setValue("applicantHasIncome", fthbData.applicant_has_income);
        setValue("applicantIncomes", fthbData.applicant_incomes || []);
        setValue("coApplicantHasIncome", fthbData.coapplicant_has_income);
        setValue("coApplicantIncomes", fthbData.coapplicant_incomes || []);
        setValue("payees", fthbData.payees || []);
        setValue(
          "certificationSignature",
          fthbData.certification_signature || "",
        );
        setValue(
          "certificationSignerName",
          fthbData.certification_signer_name || "",
        );
        setValue(
          "certificationDateTime",
          fthbData.certification_datetime
            ? new Date(fthbData.certification_datetime).toISOString()
            : "",
        );
        setValue(
          "authorizationSignature",
          fthbData.authorization_signature || "",
        );
        setValue(
          "authorizationSignerName",
          fthbData.authorization_signer_name || "",
        );
        setValue(
          "authorizationDateTime",
          fthbData.authorization_datetime
            ? new Date(fthbData.authorization_datetime).toISOString()
            : "",
        );
        setValue(
          "authorizationCoApplicantSignature",
          fthbData.coapplicant_authorization_signature || "",
        );

        setValue(
          "authorizationCoApplicantSignerName",
          fthbData.coapplicant_authorization_signer_name || "",
        );

        setValue(
          "authorizationCoApplicantDateTime",
          fthbData.coapplicant_authorization_datetime
            ? new Date(
                fthbData.coapplicant_authorization_datetime,
              ).toISOString()
            : "",
        );

        setValue("inspectionSignature", fthbData.inspection_signature || "");
        setValue("inspectionSignerName", fthbData.inspection_signer_name || "");
        setValue(
          "inspectionDateTime",
          fthbData.inspection_datetime
            ? new Date(fthbData.inspection_datetime).toISOString()
            : "",
        );
        setValue("inspectionCoApplicantSignature" as any, fthbData.inspection_coapplicant_signature || "");
        setValue("inspectionCoApplicantSignerName" as any, fthbData.inspection_coapplicant_signer_name || "");
        setValue(
          "inspectionCoApplicantDateTime" as any,
          fthbData.inspection_coapplicant_datetime
            ? new Date(fthbData.inspection_coapplicant_datetime).toISOString()
            : "",
        );
        setValue(
          "bidApplicantSignature",
          fthbData.bid_applicant_signature || "",
        );
        setValue(
          "bidApplicantSignerName",
          fthbData.bid_applicant_signer_name || "",
        );
        setValue(
          "bidApplicantDateTime",
          fthbData.bid_applicant_datetime
            ? new Date(fthbData.bid_applicant_datetime).toISOString()
            : "",
        );
        setValue(
          "bidCoApplicantSignature",
          fthbData.bid_coapplicant_signature || "",
        );
        setValue(
          "bidCoApplicantSignerName",
          fthbData.bid_coapplicant_signer_name || "",
        );
        setValue(
          "bidCoApplicantDateTime",
          fthbData.bid_coapplicant_datetime
            ? new Date(fthbData.bid_coapplicant_datetime).toISOString()
            : "",
        );
        setValue("notaryDay", fthbData.notary_day || "");
        setValue("notaryMonth", fthbData.notary_month || "");
        setValue("notaryYear", fthbData.notary_year || "");
        setValue("notaryAppearedName", fthbData.notary_appeared_name || "");
        setActiveStep(data.active_step);
      }
    } catch (error: any) {
      console.error("Error loading application:", error);

      if (error?.response?.status === 403) {
        setLoadError("Access denied. You can only view your own applications.");
      } else if (error?.response?.status === 401) {
        setLoadError("Unauthorized. Please log in again.");
        setTimeout(() => router.push("/web-auth"), 2000);
      } else if (error?.response?.status === 404) {
        setLoadError("Application not found.");
      } else {
        setLoadError(
          error?.response?.data?.message || "Failed to load application.",
        );
      }

      showToast({
        title: "Error",
        description:
          error?.response?.data?.message || "Failed to load application.",
        type: "error",
      });
    } finally {
      setLoading(false);
    }
  };

  const handleSave = async () => {
    if (isReadOnly) return;

    try {
      setLoading(true);
      const formData = watch();

      const payload = {
        applicationId,
        activeStep,

        applicant_name: formData.applicantName,
        coapplicant_name: formData.coApplicantName,
        applicant_email: formData.email,
        phone_cell: formData.phoneCell,
        phone_work: formData.phoneWork,
        phone_home: formData.phoneHome,
        applicant_area: formData.area,
        country: formData.country,
        state: formData.state,
        city: formData.city,
        is_currently_employed: formData.isCurrentlyEmployed,
        applicant_employer_name: formData.employerApplicant,
        coapplicant_employer_name: formData.employerCoApplicant,
        coapplicant_employer_address: formData.employerAddressCoApplicant,
        applicant_has_income: formData.applicantHasIncome,
        applicant_incomes: formData.applicantIncomes,
        coapplicant_has_income: formData.coApplicantHasIncome,
        coapplicant_incomes: formData.coApplicantIncomes,
        payees: formData.payees,
        certification_signature: formData.certificationSignature,
        certification_signer_name: formData.certificationSignerName,
        certification_datetime: formData.certificationDateTime,
        authorization_signature: formData.authorizationSignature,
        authorization_signer_name: formData.authorizationSignerName,
        authorization_datetime: formData.authorizationDateTime,
        coapplicant_authorization_signature:
          formData.authorizationCoApplicantSignature,

        coapplicant_authorization_signer_name:
          formData.authorizationCoApplicantSignerName,

        coapplicant_authorization_datetime:
          formData.authorizationCoApplicantDateTime,
        inspection_signature: formData.inspectionSignature,
        inspection_signer_name: formData.inspectionSignerName,
        inspection_datetime: formData.inspectionDateTime,
        inspection_coapplicant_signature: (formData as any).inspectionCoApplicantSignature,
        inspection_coapplicant_signer_name: (formData as any).inspectionCoApplicantSignerName,
        inspection_coapplicant_datetime: (formData as any).inspectionCoApplicantDateTime,
        bid_applicant_signature: formData.bidApplicantSignature,
        bid_applicant_signer_name: formData.bidApplicantSignerName,
        bid_applicant_datetime: formData.bidApplicantDateTime,
        bid_coapplicant_signature: formData.bidCoApplicantSignature,
        bid_coapplicant_signer_name: formData.bidCoApplicantSignerName,
        bid_coapplicant_datetime: formData.bidCoApplicantDateTime,
        notary_day: formData.notaryDay,
        notary_month: formData.notaryMonth,
        notary_year: formData.notaryYear,
        notary_appeared_name: formData.notaryAppearedName,
      };

      const response = await saveFTHBApplication(payload);

      if (!applicationId) {
        setApplicationId(response.data.data.applicationId);
      }

      showToast({
        title: "Success!",
        description: "Application saved successfully.",
        type: "success",
      });
    } catch (error) {
      console.error("Error saving application:", error);
      showToast({
        title: "Error",
        description: "Failed to save application. Please try again.",
        type: "error",
      });
    } finally {
      setLoading(false);
    }
  };

  const validateDocuments = async () => {
    if (!applicationId) {
      showToast({
        title: "Warning",
        description: "Please save the application first before submitting.",
        type: "warning",
      });
      return false;
    }

    try {
      const docMasterResponse = await getDocumentsByService(
        "First Time Home Buyer Program",
      );
      const requiredDocs = docMasterResponse.data.data
        .filter((doc: any) => doc.is_required === 1)
        .map((doc: any) => doc.document_name);

      const response = await getFTHBApplicationDocuments(applicationId);
      const uploadedDocs = response.data.data;
      const uploadedDocTypes = uploadedDocs.map(
        (doc: any) => doc.document_type,
      );

      const missingDocs = requiredDocs.filter(
        (doc: string) => !uploadedDocTypes.includes(doc),
      );

      if (missingDocs.length > 0) {
        showToast({
          title: "Missing Required Documents",
          description: `Please upload: ${missingDocs.join(", ")}`,
          type: "error",
          duration: 8000,
        });
        return false;
      }

      return true;
    } catch (error) {
      console.error("Error validating documents:", error);
      showToast({
        title: "Error",
        description: "Failed to validate documents. Please try again.",
        type: "error",
      });
      return false;
    }
  };

  const handleNext = async () => {
    if (isReadOnly) {
      setActiveStep((prev) => Math.min(prev + 1, 5));
      return;
    }

    const stepFields: Record<number, (keyof FirstTimeHomeBuyerFormData)[]> = {
      1: [
        "applicantName",
        "email",
        "phoneCell",
        "area",
        "country",
        "state",
        "city",
      ],
      2: ["isCurrentlyEmployed", "employerApplicant", "applicantHasIncome"],
      3: ["payees"],
      4: [
        "certificationSignature",
        "certificationSignerName",
        "authorizationSignature",
        "authorizationSignerName",
        "inspectionSignature",
        "inspectionSignerName",
        "bidApplicantSignature",
        "bidApplicantSignerName",
        "notaryDay",
        "notaryMonth",
        "notaryYear",
        "notaryAppearedName",
      ],
      5: ["documents"],
    };

    if (activeStep === 5) {
      const isValid = await trigger(stepFields[activeStep]);
      if (!isValid) return;

      if (step5ValidateFn) {
        const step5Valid = step5ValidateFn();
        if (!step5Valid) {
          return;
        }
      }

      const documentsValid = await validateDocuments();
      if (!documentsValid) {
        return;
      }

      try {
        setLoading(true);
        await handleSave();
        if (applicationId) {
          await submitFTHBApplication(applicationId);
          showToast({
            title: "Success!",
            description: "Application submitted successfully.",
            type: "success",
          });
          setTimeout(() => router.push("/thank-you"), 1500);
        } else {
          showToast({
            title: "Error",
            description:
              "No application ID found. Please save the application first.",
            type: "error",
          });
        }
      } catch (error: any) {
        console.error("Error submitting application:", error);
        showToast({
          title: "Submission Failed",
          description:
            error?.response?.data?.message ||
            "Failed to submit application. Please try again.",
          type: "error",
        });
      } finally {
        setLoading(false);
      }
    } else {
      const isValid = await trigger(stepFields[activeStep]);
      if (isValid) {
        await handleSave();
        setActiveStep((prev) => Math.min(prev + 1, 5));
      }
    }
  };

  const handlePrevious = () => {
    setActiveStep((prev) => Math.max(prev - 1, 1));
  };

  if (loading && applicationId) {
    return (
      <div className="flex justify-center items-center min-h-screen bg-gray-50">
        <div className="text-center">
          <div className="animate-spin rounded-full h-16 w-16 border-b-4 border-teal-600 mx-auto mb-4"></div>
          <p className="text-gray-600 text-lg">Loading application...</p>
        </div>
      </div>
    );
  }

  if (loadError) {
    return <UnauthorizedAccess error={loadError} />;
  }

  return (
    <>
      <section
        className="relative w-full bg-cover bg-center bg-no-repeat py-6 md:py-10 px-5 lg:px-20 rounded-lg overflow-hidden mt-5"
        style={{ backgroundImage: "url('about/about-bg.png')" }}
      >
        <div className="absolute inset-0 bg-black/40"></div>
        <div className="relative z-10 max-w-7xl mx-auto">
          <div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-6">
            <div>
              <nav className="inline-flex items-center gap-4 px-8 py-2 rounded-full bg-teal-transperent backdrop-blur-sm mb-6">
                <Link
                  href="/"
                  className="text-[15px] md:text-[17px] text-white font-medium hover:underline"
                >
                  Home
                </Link>
                <span className="text-white text-2xl leading-none">›</span>
                <Link
                  href="/first-time-home-buyer-assistance"
                  className="text-[15px] md:text-[17px] text-white font-medium hover:underline"
                >
                  First-Time Home Buyer Assistance
                </Link>
                <span className="text-white text-2xl leading-none">›</span>
                <span className="text-[15px] md:text-[17px] text-white font-medium">
                  Application form
                </span>
              </nav>
              <h1 className="text-[20px] lg:text-[35px] font-semibold text-white leading-tight md:leading-snug">
                <span className="inline-flex items-center gap-3 relative pr-[25px]">
                  First-Time Home Buyer Assistance
                  <Image
                    src="/icons/top-arrow.svg"
                    alt="Top Arrow"
                    width={36}
                    height={36}
                    className="absolute right-[0px] md:right-[-25px] lg:right-[-50px] top-[-15px]"
                  />
                </span>
              </h1>
            </div>
          </div>
        </div>
      </section>

      <section className="my-10 max-w-7xl mx-auto">
        <div className="bg-white rounded-xl shadow-sm border mb-8 px-4 py-4">
          {isReadOnly && (
            <div className="mb-4 p-3 bg-blue-50 border border-blue-200 text-blue-700 rounded-lg text-sm font-medium">
              Note: You are viewing a submitted application. Fields are
              read-only.
            </div>
          )}
          <PaginationStepper steps={steps} activeStep={activeStep} />
        </div>

        <div className="bg-white rounded-xl shadow-md p-6 md:p-8">
          {activeStep === 1 && (
            <Step1
              control={control}
              errors={errors}
              isReadOnly={isReadOnly}
              countryOptions={countryOptions}
              stateOptions={stateOptions}
              cityOptions={cityOptions}
              onCountryChange={() => {
                setValue("state", "");
                setValue("city", "");
              }}
              onStateChange={() => {
                setValue("city", "");
              }}
            />
          )}

          {activeStep === 2 && (
            <Step2
              control={control}
              errors={errors}
              isReadOnly={isReadOnly}
              watch={watch}
              setValue={setValue}
            />
          )}

          {activeStep === 3 && (
            <Step3
              control={control}
              errors={errors}
              isReadOnly={isReadOnly}
              watch={watch}
              setValue={setValue}
            />
          )}

          {activeStep === 4 && (
            <Step4
              control={control}
              errors={errors}
              isReadOnly={isReadOnly}
              setValue={setValue}
            />
          )}

          {activeStep === 5 && (
            <Step5
              control={control}
              errors={errors}
              isReadOnly={isReadOnly}
              watch={watch}
              setValue={setValue}
              applicationId={applicationId}
              setError={setError}
              clearErrors={clearErrors}
              trigger={trigger}
              onValidate={handleStep5Validate}
            />
          )}

          <div className="flex justify-between items-center mt-10 pt-6 border-t border-gray-100">
            {activeStep > 1 && (
              <Button
                onClick={handlePrevious}
                disabled={loading}
                variant="secondary"
              >
                ← Previous Step
              </Button>
            )}
            <div className="flex justify-end gap-4 ml-auto">
              {!isReadOnly && (
                <>
                  <Button
                    onClick={handleSave}
                    disabled={loading}
                    variant="dark"
                  >
                    {loading ? "Saving..." : "Save"}
                  </Button>
                  <Button
                    onClick={handleNext}
                    disabled={loading}
                    variant="primary"
                  >
                    {loading
                      ? "Processing..."
                      : activeStep === 5
                        ? "Submit"
                        : "Next"}
                  </Button>
                </>
              )}
              {isReadOnly && activeStep !== 5 && (
                <Button
                  onClick={handleNext}
                  disabled={loading}
                  variant="primary"
                >
                  Next
                </Button>
              )}
            </div>
          </div>
        </div>
      </section>
    </>
  );
}
