"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 { useToast } from "@/hooks/useToast";
import { useFormState } from "@/hooks/useFormState";
import { useFormDataLoader, toOption, safeString, safeDate } from "@/hooks/useFormDataLoader";
import { validatePositiveNumber, validateSelectOption, validateDate } from "@/lib/form-validation";
import { ToastComponent } from "@/components/common/Toast";
import { LoadingOverlay } from "@/components/common/LoadingOverlay";
import AssetTypeModal from "@/components/common/AssetTypeModel";
import BankModal from "@/components/common/BankModel";
import PlacementDatePicker from "@/fields/PlacementDate";
import TransactionTypeSelect from "@/fields/TypeOfTransaction";
import ExecutionTypeSelect from "@/fields/ExecutionType";
import BankAdviceRefNoInput from "@/fields/BankAdviceNo";
import QuantityInput from "@/fields/Quantity";
import CurrencySelect from "@/fields/Currency";
import CouponInput from "@/fields/Coupon";
import MaturityDatePicker from "@/fields/MaturityDate";
import SecurityTickerInput from "@/fields/SecurityTicker";
import SecurityNameInput from "@/fields/SecurityName";
import BankNotesInput from "@/fields/BankNotes";
import PricePerSecurityInput from "@/fields/PricePerSecurity";
import AmountDisplay from "@/fields/Amount";
import CommissionInput from "@/fields/Comission";
import ChargesAndFeesInput from "@/fields/ChargesFeesAbroad";
import FederalTurnoverTaxInput from "@/fields/FederalTurnOver";
import AssetTypeSelect from "@/fields/AssetType";
import CouponsPerYearInput from "@/fields/CouponPerYear";
import BankSelect from "@/fields/Bank";
import RelationshipManagerInput from "@/fields/RelationshipManager";
import DocumentUpload from "@/fields/FileUpload";
import TargetPriceInput from "@/fields/TargetPrice";
import RemarksInput from "@/fields/Remarks";
import PurposeInput from "@/fields/Purpose";
import CallDateInput from "@/fields/CallDate";

type FormField =
  | "placementdate"
  | "t_o_t"
  | "e_t"
  | "quantity"
  | "ticker"
  | "securityname"
  | "pricepersecurity"
  | "aassettype"
  | "m_date";

function BondFormContent() {
  
  const [placementdate, setplacementdate] = useState("");
  const [t_o_t, sett_o_t] = useState<{ label: string; value: string } | null>(null);
  const [bankadviserefno, setbankadviserefno] = useState("");
  const [quantity, setquantity] = useState("");
  const [p_currency, setp_currency] = useState<{ label: string; value: string } | null>(null);
  const [coupon, setcoupon] = useState("");
  const [m_date, setm_date] = useState("");
  const [ticker, setticker] = useState("");
  const [securityname, setsecurityname] = useState("");
  const [banknotes, setbanknotes] = useState("");
  const [pricepersecurity, setpricepersecurity] = useState("");
  const [amount, setamount] = useState("");
  const [e_t, sete_t] = useState<{ label: string; value: string } | null>(null);
  const [commission, setcommission] = useState("");
  const [chargesandfees, setchargesandfees] = useState("");
  const [federalturnovertax, setfederalturnovertax] = useState("");
  const [aassettype, setaassettype] = useState<{ label: string; value: string } | null>(null);
  const [couponperyear, setcouponperyear] = useState("");
  const [bank, setbank] = useState<{ label: string; value: string } | null>(null);
  const [relationshipmanager, setrelationshipmanager] = useState("");
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [targetprice, settargetprice] = useState("");
  const [remarks, setRemarks] = useState("");
  const [description, setDescription] = useState("");
  const [calldateone, setcalldateone] = useState("");
  const [calldatetwo, setcalldatetwo] = useState("");
  const [calldatethree, setcalldatethree] = useState("");
  const searchParams = useSearchParams();
  const editId = searchParams.get("id");
  const isEditing = useMemo(() => Boolean(editId), [editId]);
  const pageTitle = useMemo(() => (isEditing ? "Update Bond" : "Create Bond"), [isEditing]);
  const saveLabel = useMemo(() => (isEditing ? "Update" : "Save"), [isEditing]);
  const savingLabel = useMemo(() => (isEditing ? "Updating..." : "Saving..."), [isEditing]);
  const [isSaving, setIsSaving] = useState(false);
  const [showBankModal, setShowBankModal] = useState(false);
  const [showAssetTypeModal, setShowAssetTypeModal] = useState(false);

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

  // Load existing data for edit mode
  const { loadingExisting } = useFormDataLoader({
    editId,
    apiEndpoint: "/api/fixedincome/bond",
    transformData: (attributes) => {
      setplacementdate(safeDate(attributes.t_date));
      sett_o_t(toOption(attributes.t_o_t as string | number | null | undefined, attributes.t_o_t_label as string | number | null | undefined));
      setbankadviserefno(safeString(attributes.r_no || attributes.bank_advice_ref_no));
      setquantity(safeString(attributes.quantity));
      setcoupon(safeString(attributes.knock || attributes.coupon));
      setm_date(safeDate(attributes.m_date, ""));
      setticker(safeString(attributes.ticker));
      setsecurityname(safeString(attributes.isin || attributes.securityname));
      setbanknotes(safeString(attributes.b_notes || attributes.bank_notes));
      setpricepersecurity(safeString(attributes.price));
      setamount(safeString(attributes.amount));
      sete_t(toOption(attributes.e_t as string | number | null | undefined, attributes.e_t_label as string | number | null | undefined));
      setcommission(safeString(attributes.commission));
      setchargesandfees(safeString(attributes.b_1));
      setfederalturnovertax(safeString(attributes.b_2));
      setaassettype(toOption(attributes.a_type as string | number | null | undefined, attributes.a_type_label as string | number | null | undefined));
      setcouponperyear(safeString(attributes.duration));
      setbank(toOption(attributes.bank_id as string | number | null | undefined, attributes.bank_name as string | number | null | undefined));
      setrelationshipmanager(safeString(attributes.r_m || attributes.relationshipmanager));
      settargetprice(safeString(attributes.t_price));
      setRemarks(safeString(attributes.remarks));
      setDescription(safeString(attributes.purpose || attributes.description));
      setp_currency(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));
      setcalldateone(safeDate(attributes.c_date, ""));
      setcalldatetwo(safeDate(attributes.c_date2, ""));
      setcalldatethree(safeDate(attributes.c_date3, ""));
    },
    onError: () => {
      showToast("error", "Unable to load bond details for editing.");
    },
  });

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

  const hasQuantity = useMemo(() => quantity.trim() !== "", [quantity]);
  const hasPrice = useMemo(() => pricepersecurity.trim() !== "", [pricepersecurity]);
  const hasAmountInput = useMemo(() => amount.trim() !== "", [amount]);

  const quantityNumber = useMemo(() => parseNumber(quantity), [quantity]);
  const priceNumber = useMemo(() => parseNumber(pricepersecurity), [pricepersecurity]);
  const amountNumber = useMemo(() => (hasAmountInput ? parseNumber(amount) : 0), [hasAmountInput, amount]);

  const computedAmount = useMemo(
    () => (hasQuantity && hasPrice ? quantityNumber * priceNumber : 0),
    [hasQuantity, hasPrice, quantityNumber, priceNumber]
  );
  const totalAmount = useMemo(
    () => (hasAmountInput ? amountNumber : computedAmount),
    [hasAmountInput, amountNumber, computedAmount]
  );

  const commissionValue = useMemo(() => parseNumber(commission), [commission]);
  const chargesValue = useMemo(() => parseNumber(chargesandfees), [chargesandfees]);
  const taxValue = useMemo(() => parseNumber(federalturnovertax), [federalturnovertax]);
  const netAmount = useMemo(
    () => totalAmount - commissionValue - chargesValue - taxValue,
    [totalAmount, commissionValue, chargesValue, taxValue]
  );
  const amountDisplayValue = useMemo(
    () => (hasAmountInput ? amount : hasQuantity && hasPrice ? computedAmount.toFixed(2) : ""),
    [hasAmountInput, amount, hasQuantity, hasPrice, computedAmount]
  );

  const footerData = useMemo(
    () => [
      { label: "Amount", value: formatCurrency(totalAmount) },
      { label: "Commission", value: formatCurrency(commissionValue) },
      { label: "Charges and fees abroad", value: formatCurrency(chargesValue) },
      { label: "Federal turnover tax", value: formatCurrency(taxValue) },
      { label: "Maturity", value: m_date || "—" },
    ],
    [totalAmount, commissionValue, chargesValue, taxValue, m_date]
  );

  const resetForm = useCallback(() => {
    setplacementdate(getTodayDate());
    sett_o_t(null);
    sete_t(null);
    setp_currency(null);
    setaassettype(null);
    setbank(null);
    setSelectedFile(null);
    setbankadviserefno("");
    setquantity("");
    setticker("");
    setsecurityname("");
    setpricepersecurity("");
    setamount("");
    setcoupon("");
    setcouponperyear("");
    setm_date("");
    setcommission("");
    setchargesandfees("");
    setfederalturnovertax("");
    settargetprice("");
    setrelationshipmanager("");
    setDescription("");
    setbanknotes("");
    setRemarks("");
    setcalldateone("");
    setcalldatetwo("");
    setcalldatethree("");
    setErrors({});
  }, [setErrors]);

  const validateField = useCallback((field: FormField): string | undefined => {
    switch (field) {
      case "placementdate":
        return validateDate(placementdate, "Placement date");
      case "t_o_t":
        return validateSelectOption(t_o_t, "Type of transaction");
      case "quantity":
        return validatePositiveNumber(quantity, "Quantity");
      case "m_date":
        return validateDate(m_date, "Maturity date");
      case "ticker":
        if (!ticker.trim()) return "Security ticker/ISIN is required.";
        return;
      case "securityname":
        if (!securityname.trim()) return "Security name is required.";
        return;
      case "pricepersecurity":
        return validatePositiveNumber(pricepersecurity, "Price per security");
      case "aassettype":
        return validateSelectOption(aassettype, "Asset type");
      default:
        return undefined;
    }
  }, [placementdate, t_o_t, quantity, m_date, ticker, securityname, pricepersecurity, aassettype]);

  const validateForm = useCallback(() => {
    const fieldsToValidate: FormField[] = [
      "placementdate",
      "t_o_t",
      "quantity",
      "m_date",
      "ticker",
      "securityname",
      "pricepersecurity",
      "aassettype",
    ];
    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({});
    setIsSaving(true);

    const payload: Record<string, unknown> = {
      t_date: placementdate,
      t_o_t: t_o_t?.value ?? "",
      r_no: bankadviserefno,
      quantity: parseNumber(quantity),
      knock: coupon,
      m_date,
      ticker,
      isin: securityname,
      b_notes: banknotes,
      price: parseNumber(pricepersecurity),
      amount: hasAmountInput ? parseNumber(amount) : totalAmount,
      e_t: e_t?.value ?? "",
      commission: commissionValue,
      b_1: chargesValue,
      b_2: taxValue,
      a_class:1431,
      a_type: aassettype?.value ?? "",
      duration: couponperyear,
      bank_id: bank?.value ?? "",
      r_m: relationshipmanager,
      r_link: selectedFile,
      t_price: targetprice,
      remarks,
      purpose: description,
      c_date: calldateone,
      c_date2: calldatetwo,
      c_date3: calldatethree,
      p_currency: p_currency?.value ?? "",
    };

    if (isEditing && editId) {
      payload.id = editId;
    }

    const endpoint = isEditing ? "/api/fixedincome/bond/update" : "/api/fixedincome/bond/create";
    const actionLabel = isEditing ? "update" : "create";

    try {
      const response = await fetch(endpoint, {
        method: "POST",
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        const errorBody = await response.text();
        throw new Error(
          `Bond ${actionLabel} failed with status ${response.status} (${response.statusText}): ${errorBody || "No response body"}`
        );
      }

      const result = await response.json();
      const isSuccess = result?.success === true || result?.status === "success";

      if (isSuccess) {
        const successMessage = isEditing ? "Bond updated successfully!" : "Bond saved successfully!";
        showToast("success", successMessage);
        if (!isEditing) {
          resetForm();
        }
      } else {
        const errorMessage =
          typeof result?.message === "string"
            ? result.message
            : "Unexpected response received from the server.";
        showToast("error", errorMessage);
      }
    } catch (error) {
      const fallbackMessage =
        error instanceof Error && error.message
          ? error.message
          : `Failed to ${actionLabel} bond`;
      showToast("error", fallbackMessage);
    } finally {
      setIsSaving(false);
    }
  }, [isEditing, editId, validateForm, setErrors, showToast, placementdate, t_o_t, bankadviserefno, quantity, coupon, m_date, ticker, securityname, banknotes, pricepersecurity, hasAmountInput, amount, totalAmount, e_t, commissionValue, chargesValue, taxValue, aassettype, couponperyear, bank, relationshipmanager, selectedFile, targetprice, remarks, description, calldateone, calldatetwo, calldatethree, p_currency, resetForm]);

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

  const handleCloseAssetTypeModal = useCallback(() => {
    setShowAssetTypeModal(false);
  }, []);

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

  const breadcrumbs = useMemo(
    () => [
      { label: "Home", href: "/" },
      { label: "Bond", href: "/fixedincome/bond" },
      { label: pageTitle },
    ],
    [pageTitle]
  );

  return (
    <>
      <ToastComponent toast={toast} />
      <LoadingOverlay isLoading={loadingExisting} message="Loading bond 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={breadcrumbs}
          />

          <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">
                {/* Placement Date */}
                <PlacementDatePicker
                placementdate={placementdate}
                setplacementdate={setplacementdate}
                clearError={clearError}
                errors={errors}
                handleFieldBlur={handleFieldBlur}
                validateField={validateField}
                formatDateToString={formatDateToString}
              />

                {/* Type of Transaction */}
                <TransactionTypeSelect
                  t_o_t={t_o_t}
                  sett_o_t={sett_o_t}
                  clearError={clearError}
                  errors={errors}
                  handleFieldBlur={handleFieldBlur}
                  validateField={validateField}
                />

                {/* Execution Type */}
                <ExecutionTypeSelect
                  e_t={e_t}
                  sete_t={sete_t}
                  clearError={clearError}
                  errors={errors}
                  handleFieldBlur={handleFieldBlur}
                  validateField={validateField}
                />

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

                {/* Quantity */}
                <QuantityInput
                  quantity={quantity}
                  setquantity={setquantity}
                  clearError={clearError}
                  errors={errors}
                  handleFieldBlur={handleFieldBlur}
                  validateField={validateField}
                />

                {/* Currency */}
                <CurrencySelect
                  p_currency={p_currency}
                  setp_currency={setp_currency}
                />

                {/* Coupon */}
                <CouponInput
                  coupon={coupon}
                  setcoupon={setcoupon}
                />

                {/* Maturity Date */}
                <MaturityDatePicker
                  maturitydate={m_date}
                  setmaturitydate={setm_date}
                  formatDateToString={formatDateToString}
                />

                {/* Security Ticker/ISIN */}
                <SecurityTickerInput
                  ticker={ticker}
                  setticker={setticker}
                  clearError={clearError}
                  errors={errors}
                  handleFieldBlur={handleFieldBlur}
                  validateField={validateField}
                />

                {/* Security Name */}
                <SecurityNameInput
                  securityname={securityname}
                  setsecurityname={setsecurityname}
                  clearError={clearError}
                  errors={errors}
                  handleFieldBlur={handleFieldBlur}
                  validateField={validateField}
                />

                {/* Bank Notes */}
                <BankNotesInput
                  banknotes={banknotes}
                  setbanknotes={setbanknotes}
                />

                {/* Price per Security */}
                <PricePerSecurityInput
                  pricepersecurity={pricepersecurity}
                  setpricepersecurity={setpricepersecurity}
                  clearError={clearError}
                  errors={errors}
                  handleFieldBlur={handleFieldBlur}
                  validateField={validateField}
                />

                {/* Amount */}
                <AmountDisplay
                  amountDisplayValue={amountDisplayValue}
                />

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

                {/* Charges & Fees Abroad */}
                <ChargesAndFeesInput
                  chargesandfees={chargesandfees}
                  setchargesandfees={setchargesandfees}
                />

                {/* Federal Turnover Tax */}
                <FederalTurnoverTaxInput
                  federalturnovertax={federalturnovertax}
                  setfederalturnovertax={setfederalturnovertax}
                />

                {/* Asset Type */}
                <AssetTypeSelect
                  aassettype={aassettype}
                  setaassettype={setaassettype}
                  clearError={clearError}
                  errors={errors}
                  handleFieldBlur={handleFieldBlur}
                  validateField={validateField}
                  setShowAssetTypeModal={setShowAssetTypeModal}
                />

                {/* No. of Coupons per Year */}
                <CouponsPerYearInput
                  couponperyear={couponperyear}
                  setcouponperyear={setcouponperyear}
                />

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

                {/* Relationship Manager */}
                <RelationshipManagerInput
                  relationshipmanager={relationshipmanager}
                  setrelationshipmanager={setrelationshipmanager}
                />

                {/* File Upload */}
                <DocumentUpload
                  setSelectedFile={setSelectedFile}
                />

                {/* Target Price */}
                <TargetPriceInput
                  targetprice={targetprice}
                  settargetprice={settargetprice}
                />

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

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

                {/* Call Date 1 */}
                <CallDateInput
                  label="Call Date 1"
                  value={calldateone}
                  setValue={setcalldateone}
                  formatDateToString={formatDateToString}
                />

                {/* Call Date 2 */}
                <CallDateInput
                  label="Call Date 2"
                  value={calldatetwo}
                  setValue={setcalldatetwo}
                  formatDateToString={formatDateToString}
                />

                {/* Call Date 3 */}
                <CallDateInput
                  label="Call Date 3"
                  value={calldatethree}
                  setValue={setcalldatethree}
                  formatDateToString={formatDateToString}
                />
              </div>

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

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