"use client";

import { Suspense, useEffect, useState, useMemo, useCallback } from "react";
import { useSearchParams } from "next/navigation";
import FloatingFooter from "@/components/FloatingFooter";
import { FormSectionHeading } from "@/components/ui/FormSectionHeading";
import { getTodayDate, formatDateToString } from "@/lib/date-utils";
import { parseNumber, formatCurrency } from "@/lib/number-utils";
import { CurrencyConversionFormField } from "@/components/validation/FormFields";
import { useToast } from "@/hooks/useToast";
import { useFormState } from "@/hooks/useFormState";
import { useFormDataLoader, toOption, safeString, safeDate } from "@/hooks/useFormDataLoader";
import { useFormSubmission } from "@/hooks/useFormSubmission";
import { validatePositiveNumber, validateSelectOption, validateDate } from "@/lib/form-validation";
import { ToastComponent } from "@/components/common/Toast";
import { LoadingOverlay } from "@/components/common/LoadingOverlay";
import BankModal from "@/components/common/BankModel";
import PlacementDatePicker from "@/fields/PlacementDate";
import CurrencyBoughtSelect from "@/fields/CurrencyBought";
import CurrencySoldSelect from "@/fields/CurrencySold";
import AmountBaseCurrency from "@/fields/AmountBaseCurrency";
import RateOfSwap from "@/fields/RateOfSwap";
import AmountSwapped from "@/fields/AmountSwapped";
import BankAdviceRefNoInput from "@/fields/BankAdviceNo";
import CommissionInput from "@/fields/Comission";
import ChargesAndFeesInput from "@/fields/ChargesFeesAbroad";
import FederalTurnoverTaxInput from "@/fields/FederalTurnOver";
import BankSelect from "@/fields/Bank";
import RemarksInput from "@/fields/Remarks";
import PurposeInput from "@/fields/Purpose";

function CurrencyConversionFormContent() {
  const [placementdate, setplacementdate] = useState("");
  const [currencybought, setcurrencybought] = useState<{ label: string; value: string } | null>(null);
  const [currencysold, setcurrencysold] = useState<{ label: string; value: string } | null>(null);
  const [amountbasecurrency, setamountbasecurrency] = useState("");
  const [conversionrate, setconversionrate] = useState("");
  const [amountconverted, setamountconverted] = useState("");
  const [bankadviserefno, setbankadviserefno] = useState("");
  const [commission, setcommission] = useState("");
  const [chargesandfees, setchargesandfees] = useState("");
  const [federalturnovertax, setfederalturnovertax] = useState("");
  const [bank, setbank] = useState<{ label: string; value: string } | null>(null);
  const [remarks, setRemarks] = useState("");
  const [description, setDescription] = useState("");
  const [showBankModal, setShowBankModal] = useState(false);

  const searchParams = useSearchParams();
  const editId = searchParams.get("id");
  const isEditing = Boolean(editId);
  const pageTitle = useMemo(
    () => (isEditing ? "Update Currency Conversion" : "Create Currency Conversion"),
    [isEditing]
  );
  const saveLabel = useMemo(() => (isEditing ? "Update" : "Save"), [isEditing]);
  const savingLabel = useMemo(() => (isEditing ? "Updating..." : "Saving..."), [isEditing]);

  // Common hooks
  const { toast, showToast } = useToast();
  const { errors, setErrors, clearError, handleFieldBlur, formRef } = useFormState<CurrencyConversionFormField>();
  const { isSaving, submitForm } = useFormSubmission();

  // Load existing data for edit mode
  const { loadingExisting } = useFormDataLoader({
    editId,
    apiEndpoint: "/api/currencyconversion",
    transformData: (attributes) => {
      setplacementdate(safeDate(attributes.t_date));
      setcurrencybought(
        toOption(
          (attributes.p_currency ?? attributes.purchase_currency_code) as string | number | null | undefined,
          (attributes.p_currency_label ?? attributes.purchase_currency_code) as string | number | null | undefined
        )
      );
      setcurrencysold(
        toOption(
          (attributes.c_currency ?? attributes.sold) as string | number | null | undefined,
          (attributes.c_currency_label ?? attributes.sold) as string | number | null | undefined
        )
      );
      setamountbasecurrency(safeString(attributes.price));
      setconversionrate(safeString(attributes.quantity));
      setamountconverted(safeString(attributes.amount));
      setbankadviserefno(safeString(attributes.r_no));
      setcommission(safeString(attributes.commission));
      setchargesandfees(safeString(attributes.b_1));
      setfederalturnovertax(safeString(attributes.b_2));
      setbank(toOption(attributes.bank_id as string | number | null | undefined, attributes.bank_name as string | number | null | undefined));
      setRemarks(safeString(attributes.remarks));
      setDescription(safeString(attributes.purpose));
    },
    onError: () => {
      showToast("error", "Unable to load currency conversion details for editing.");
    },
  });

  useEffect(() => {
    setplacementdate(getTodayDate());
  }, []);

  const amountBaseValue = useMemo(() => parseNumber(amountbasecurrency), [amountbasecurrency]);
  const conversionRateValue = useMemo(() => parseNumber(conversionrate), [conversionrate]);
  const derivedConvertedAmount = useMemo(() => {
    if (amountBaseValue > 0 && conversionRateValue > 0) {
      return amountBaseValue * conversionRateValue;
    }
    return parseNumber(amountconverted);
  }, [amountBaseValue, conversionRateValue, amountconverted]);

  const amountConvertedDisplay = useMemo(() => {
    return derivedConvertedAmount > 0 ? derivedConvertedAmount.toFixed(2) : amountconverted;
  }, [derivedConvertedAmount, amountconverted]);

  const commissionValue = useMemo(() => parseNumber(commission), [commission]);
  const chargesValue = useMemo(() => parseNumber(chargesandfees), [chargesandfees]);
  const taxValue = useMemo(() => parseNumber(federalturnovertax), [federalturnovertax]);
  const netAmount = useMemo(
    () => derivedConvertedAmount - commissionValue - chargesValue - taxValue,
    [derivedConvertedAmount, commissionValue, chargesValue, taxValue]
  );

  const footerData = useMemo(
    () => [
      { label: "Gross Amount", value: formatCurrency(derivedConvertedAmount) },
      { label: "Commission", value: formatCurrency(commissionValue) },
      { label: "Charges", value: formatCurrency(chargesValue) },
      { label: "Tax", value: formatCurrency(taxValue) },
      { label: "Net Amount", value: formatCurrency(netAmount) },
    ],
    [derivedConvertedAmount, commissionValue, chargesValue, taxValue, netAmount]
  );

  const resetForm = useCallback(() => {
    setplacementdate(getTodayDate());
    setcurrencybought(null);
    setcurrencysold(null);
    setamountbasecurrency("");
    setconversionrate("");
    setamountconverted("");
    setbank(null);
    setbankadviserefno("");
    setcommission("");
    setchargesandfees("");
    setfederalturnovertax("");
    setDescription("");
    setRemarks("");
    setErrors({});
  }, [setErrors]);

  const validateField = useCallback(
    (field: CurrencyConversionFormField): string | undefined => {
      switch (field) {
        case "placementdate":
          return validateDate(placementdate, "Placement date");
        case "currencyBought":
          return validateSelectOption(currencybought, "Currency bought");
        case "currencySold":
          return validateSelectOption(currencysold, "Currency sold");
        case "amountBase":
          return validatePositiveNumber(amountbasecurrency, "Amount (base currency)");
        case "conversionRate":
          return validatePositiveNumber(conversionrate, "Conversion rate");
        default:
          return undefined;
      }
    },
    [placementdate, currencybought, currencysold, amountbasecurrency, conversionrate]
  );

  const validateForm = useCallback(() => {
    const fieldsToValidate: CurrencyConversionFormField[] = [
      "placementdate",
      "currencyBought",
      "currencySold",
      "amountBase",
      "conversionRate",
    ];
    const newErrors: Record<string, string> = {};
    fieldsToValidate.forEach((field) => {
      const message = validateField(field);
      if (message) newErrors[field] = message;
    });
    return newErrors;
  }, [validateField]);

  const handleSubmit = useCallback(
    async (e: React.FormEvent<HTMLFormElement>) => {
      e.preventDefault();

      const validationErrors = validateForm();
      if (Object.keys(validationErrors).length > 0) {
        setErrors(validationErrors);
        return;
      }

      setErrors({});

      await submitForm({
        createEndpoint: "/api/currencyconversion",
        updateEndpoint: "/api/currencyconversion/update",
        getPayload: () => ({
          CurrencyConversion: {
            t_date: placementdate,
            p_currency: currencybought?.value ?? "",
            c_currency: currencysold?.value ?? "",
            price: parseNumber(amountbasecurrency),
            quantity: parseNumber(conversionrate),
            amount: derivedConvertedAmount,
            r_no: bankadviserefno,
            commission: commissionValue,
            b_1: chargesandfees,
            b_2: federalturnovertax,
            a_class: 1465,
            a_type: 1400,
            bank_id: bank?.value ?? "",
            remarks,
            purpose: description,
            r_link: "",
          },
        }),
        isEditing,
        editId,
        onSuccess: (message) => {
          showToast("success", message);
          if (!isEditing) {
            resetForm();
          }
        },
        onError: (message) => {
          showToast("error", message);
        },
        createSuccessMessage: "Currency conversion saved successfully!",
        updateSuccessMessage: "Currency conversion updated successfully!",
      });
    },
    [
      validateForm,
      setErrors,
      submitForm,
      placementdate,
      currencybought,
      currencysold,
      amountbasecurrency,
      conversionrate,
      derivedConvertedAmount,
      bankadviserefno,
      commissionValue,
      chargesandfees,
      federalturnovertax,
      bank,
      remarks,
      description,
      isEditing,
      editId,
      showToast,
      resetForm,
    ]
  );

  const handleSave = useCallback(() => {
    if (!isSaving && !loadingExisting) {
      formRef.current?.requestSubmit();
    }
  }, [isSaving, loadingExisting, formRef]);

  const handleCloseBankModal = useCallback(() => {
    setShowBankModal(false);
  }, []);

  return (
    <>
      <ToastComponent toast={toast} />
      <LoadingOverlay isLoading={loadingExisting} message="Loading currency conversion data..." />
      <div className="container mx-auto mt-6">
        <div className="bg-white rounded-lg shadow-md border-0">
          <FormSectionHeading
            title={pageTitle}
            eyebrow="Key Details"
            showBackButton
            icon={<i className="bx bx-line-chart" aria-hidden="true" />}
            breadcrumbs={useMemo(
              () => [
                { label: "Home", href: "/" },
                { label: "Currency Conversion", href: "/cash/currencyconversion" },
                { label: pageTitle },
              ],
              [pageTitle]
            )}
          />

          <div className="p-6 md:p-8 bg-slate-50/60">
            <form ref={formRef} onSubmit={handleSubmit} method="post">
              <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
                <PlacementDatePicker<CurrencyConversionFormField>
                placementdate={placementdate}
                setplacementdate={setplacementdate}
                clearError={clearError}
                errors={errors}
                handleFieldBlur={handleFieldBlur}
                validateField={validateField}
                formatDateToString={formatDateToString}
              />

          {/* Currency Bought */}
          <CurrencyBoughtSelect<CurrencyConversionFormField>
            currencybought={currencybought}
            setcurrencybought={setcurrencybought}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

          {/* Currency Sold */}
          <CurrencySoldSelect<CurrencyConversionFormField>
            currencysold={currencysold}
            setcurrencysold={setcurrencysold}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

          {/* Amount (Base Currency) */}
          <AmountBaseCurrency<CurrencyConversionFormField>
            amountbasecurrency={amountbasecurrency}
            setamountbasecurrency={setamountbasecurrency}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

          {/* Conversion Rate */}
          <RateOfSwap<CurrencyConversionFormField>
            rateofswap={conversionrate}
            setrateofswap={setconversionrate}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

          {/* Amount (Currency Converted) */}
          <AmountSwapped
            amountSwappedDisplay={amountConvertedDisplay}
          />

          {/* Bank Advice Ref No */}
          <BankAdviceRefNoInput
            bankadviserefno={bankadviserefno}
            setbankadviserefno={setbankadviserefno}
          />

          {/* Commission */}
          <CommissionInput
            commission={commission}
            setcommission={setcommission}
          />

          {/* Charges and fees abroad */}
          <ChargesAndFeesInput
            chargesandfees={chargesandfees}
            setchargesandfees={setchargesandfees}
          />

          {/* Federal turnover tax */}
          <FederalTurnoverTaxInput
            federalturnovertax={federalturnovertax}
            setfederalturnovertax={setfederalturnovertax}
          />

          {/* Bank */}
          <BankSelect
            bank={bank}
            setbank={setbank}
            setShowBankModal={setShowBankModal}
          />

          {/* Remarks / Comments */}
          <RemarksInput
            remarks={remarks}
            setRemarks={setRemarks}
          />

          {/* Purpose */}
          <PurposeInput
            description={description}
            setDescription={setDescription}
          />

        </div>

        <div className="pb-10" />
      </form>
    </div>
  </div>
      </div>
      {showBankModal && (
        <BankModal isOpen={showBankModal} onClose={handleCloseBankModal} />
      )}
      <FloatingFooter
        data={footerData}
        onSave={handleSave}
        isSaving={isSaving || loadingExisting}
        saveLabel={saveLabel}
        savingLabel={savingLabel}
      />
    </>
  );
}

export default function CurrencyConversionForm() {
  return (
    <Suspense fallback={<div className="p-6 text-center text-sm text-slate-500">Loading form…</div>}>
      <CurrencyConversionFormContent />
    </Suspense>
  );
}
