"use client";

import { useEffect, useState, Suspense, 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 { logger } from "@/lib/logger";
import BankModal from "@/components/common/BankModel";
import SecurityTickerInput from "@/fields/SecurityTicker";
import SecurityNameInput from "@/fields/SecurityName";
import PlacementDatePicker from "@/fields/PlacementDate";
import PremiumPaidInput from "@/fields/PremiumPaid";
import ExpirationDateInput from "@/fields/ExpirationDate";
import OptionTypeSelect from "@/fields/TypeOfOption";
import TransactionTypeSelect from "@/fields/TypeOfTransaction";
import OptionStyleSelect from "@/fields/OptionStyle";
import BankAdviceRefNoInput from "@/fields/BankAdviceNo";
import QuantityInput from "@/fields/Quantity";
import BankNotesInput from "@/fields/BankNotes";
import StrikePriceInput from "@/fields/StrikePrice";
import SpotRateInput from "@/fields/SpotPrice";
import OptionStartDateInput from "@/fields/OptionStartDate";
import MaxExposureInput from "@/fields/MaxExpourse";
import CommissionInput from "@/fields/Comission";
import ChargesAndFeesInput from "@/fields/ChargesFeesAbroad";
import FederalTurnoverTaxInput from "@/fields/FederalTurnOver";
import CurrencySelect from "@/fields/Currency";
import BankSelect from "@/fields/Bank";
import RelationshipManagerInput from "@/fields/RelationshipManager";
import RemarksInput from "@/fields/Remarks";
import PurposeInput from "@/fields/Purpose";
import DocumentUpload from "@/fields/FileUpload";
import KnockAmountWithSelect from "@/fields/KnockAmount";
import KnockTypeToggle from "@/fields/KnockAmountRadio";

type FormField =
  | "placementdate"
  | "t_o_t"
  | "t_o_option"
  | "e_t"
  | "quantity"
  | "ticker"
  | "securityname"
  | "premiumpaid"
  | "strikeprice"
  | "spotrate"

type FormErrors = Partial<Record<FormField, string>>;

function CommodityOptionFormContent() {

  const [t_o_t, sett_o_t] = useState<{ label: string; value: string } | null>(null);
  const [t_o_option, sett_o_option] = useState<{ label: string; value: string } | null>(null);
  const [optionstyle, setoptionstyle] = useState<{ label: string; value: string } | null>(null);
  const [e_t, sete_t] = useState<{ label: string; value: string } | null>(null);
  const [p_currency, setp_currency] = useState<{ label: string; value: string } | null>(null);
  const [bank, setbank] = useState<{ label: string; value: string } | null>(null);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [bankadviserefno, setbankadviserefno] = useState("");
  const [placementdate, setplacementdate] = useState("");
  const [premiumpaid, setpremiumpaid] = useState("");
  const [expirydate, setexpirydate] = useState("");
  const [strikeprice, setstrikeprice] = useState("");
  const [spotprice, setspotprice] = useState("");
  const [knockT, setKnockT] = useState("1");
  const [knockList, setKnockList] = useState<{ label: string; value: string } | null>(null);
  const [optionstartdate, setoptionstartdate] = useState("");
  const [maxexposure, setmaxexposure] = useState("");
  const [knockamount, setknockamount] = useState("");
  const [quantity, setquantity] = useState("");
  const [ticker, setticker] = useState("");
  const [securityname, setsecurityname] = useState("");
  const [amount, setamount] = useState("");
  const [commission, setcommission] = useState("");
  const [chargesandfees, setchargesandfees] = useState("");
  const [federalturnovertax, setfederalturnovertax] = useState("");
  const [relationshipmanager, setrelationshipmanager] = useState("");
  const [description, setDescription] = useState("");
  const [banknotes, setbanknotes] = useState("");
  const [remarks, setRemarks] = useState("");
  const [showBankModal, setShowBankModal] = useState(false);

  const searchParams = useSearchParams();
  const editId = searchParams.get("id");
  
  const isEditing = useMemo(() => Boolean(editId), [editId]);
  const pageTitle = useMemo(
    () => (isEditing ? "Update Commodity Options" : "Create New Commodity Options"),
    [isEditing]
  );
  const [isSaving, setIsSaving] = 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/commodity/derivatives/option",
    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));
      sett_o_option(toOption(attributes.t_o_o as string | number | null | undefined, attributes.t_o_o_label as string | number | null | undefined));
      setoptionstyle(toOption(attributes.o_s as string | number | null | undefined, attributes.o_s_label as string | number | null | undefined));
      sete_t(toOption(attributes.e_t as string | number | null | undefined, attributes.e_t_label as string | number | null | undefined));
      setbank(toOption(attributes.bank_id as string | number | null | undefined, attributes.bank_name as string | number | null | undefined));
      setp_currency(toOption(attributes.p_currency as string | number | null | undefined, attributes.p_currency_label as string | number | null | undefined));
      setquantity(safeString(attributes.quantity));
      setticker(safeString(attributes.ticker));
      setsecurityname(safeString(attributes.isin));
      setpremiumpaid(safeString(attributes.premium));
      setexpirydate(safeDate(attributes.m_date, ""));
      setstrikeprice(safeString(attributes.price));
      setspotprice(safeString(attributes.t_price));
      setoptionstartdate(safeDate(attributes.p_date, ""));
      setamount(safeString(attributes.amount));
      setcommission(safeString(attributes.commission));
      setchargesandfees(safeString(attributes.b_1));
      setfederalturnovertax(safeString(attributes.b_2));
      setrelationshipmanager(safeString(attributes.r_m));
      setDescription(safeString(attributes.purpose));
      setbanknotes(safeString(attributes.b_notes));
      setRemarks(safeString(attributes.remarks));
      setbankadviserefno(safeString(attributes.r_no));
      setknockamount(safeString(attributes.knock));
      setKnockT(safeString(attributes.knock_t, "1"));
      setKnockList(toOption(attributes.knock as string | number | null | undefined, attributes.knock_label as string | number | null | undefined));
    },
    onError: () => {
      showToast("error", "Failed to load commodity option data. Please refresh the page.");
    },
  });

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

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

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

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

  // Update Max Exposure to match totalAmount
  useEffect(() => {
    if (totalAmount > 0) {
      setmaxexposure(formatCurrency(totalAmount));
    } else {
      setmaxexposure("");
    }
  }, [totalAmount]);

  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 footerData = useMemo(
    () => [
      { label: "Total Amount", value: formatCurrency(totalAmount) },
      { label: "Commission", value: formatCurrency(commissionValue) },
      { label: "Charges", value: formatCurrency(chargesValue) },
      { label: "Tax", value: formatCurrency(taxValue) },
      { label: "Net Amount", value: formatCurrency(netAmount) },
    ],
    [totalAmount, commissionValue, chargesValue, taxValue, netAmount]
  );

  const resetForm = useCallback(() => {
    setplacementdate(getTodayDate());
    sett_o_t(null);
    sett_o_option(null);
    setoptionstyle(null);
    sete_t(null);
    setp_currency(null);
    setbank(null);
    setSelectedFile(null);
    setbankadviserefno("");
    setquantity("");
    setticker("");
    setsecurityname("");
    setpremiumpaid("");
    setexpirydate("");
    setstrikeprice("");
    setspotprice("");
    setoptionstartdate("");
    setamount("");
    setcommission("");
    setchargesandfees("");
    setfederalturnovertax("");
    setrelationshipmanager("");
    setDescription("");
    setbanknotes("");
    setRemarks("");
    setknockamount("");
    setKnockT("1");
    setErrors({});
  }, [setErrors]);

  const validateField = useCallback(
    (field: FormField): string | undefined => {
      switch (field) {
        case "placementdate":
          return validateDate(placementdate, "Placement 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 "premiumpaid":
          return validatePositiveNumber(premiumpaid, "Premium paid / received");
        case "t_o_option":
          return validateSelectOption(t_o_option, "Type of option");
        case "t_o_t":
          return validateSelectOption(t_o_t, "Type of transaction");
        case "quantity":
          return validatePositiveNumber(quantity, "Quantity under option");
        case "strikeprice":
          return validatePositiveNumber(strikeprice, "Strike price");
        case "e_t":
          return validateSelectOption(e_t, "Execution type");
        default:
          return undefined;
      }
    },
    [placementdate, ticker, securityname, premiumpaid, t_o_option, t_o_t, quantity, strikeprice, e_t]
  );

  const validateForm = useCallback(() => {
    const fieldsToValidate: FormField[] = [
      "placementdate",
      "ticker",
      "securityname",
      "premiumpaid",
      "t_o_option",
      "t_o_t",
      "quantity",
      "strikeprice",
      "e_t",
    ];
    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);
      
      // Get the first error field name and message
      const firstErrorField = Object.keys(validationErrors)[0];
      const firstErrorMessage = validationErrors[firstErrorField as FormField];
      
      // Scroll to the first error field
      setTimeout(() => {
        const errorElement = document.querySelector(`[name="${firstErrorField}"], [data-field="${firstErrorField}"]`) ||
                            document.querySelector(`input[id*="${firstErrorField}"], select[id*="${firstErrorField}"]`);
        if (errorElement) {
          errorElement.scrollIntoView({ behavior: "smooth", block: "center" });
          // Try to focus the input if it's focusable
          if (errorElement instanceof HTMLElement && 'focus' in errorElement) {
            (errorElement as HTMLElement).focus();
          }
        }
      }, 100);
      
      // Show simple error message - fields will show specific errors with red highlighting
      const errorCount = Object.keys(validationErrors).length;
      showToast("error", `Please fix ${errorCount} required field${errorCount > 1 ? 's' : ''} before saving.`);
      logger.debug("Validation errors", { validationErrors });
      return;
    }

    setErrors({});
    setIsSaving(true);

    // Convert file to base64 if file is selected
    let fileBase64 = "";
    if (selectedFile) {
      try {
        fileBase64 = await new Promise<string>((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = () => {
            const result = reader.result as string;
            // Remove data URL prefix (e.g., "data:application/pdf;base64,")
            const base64 = result.split(",")[1] || result;
            resolve(base64);
          };
          reader.onerror = (error) => reject(error);
          reader.readAsDataURL(selectedFile);
        });
      } catch (fileError) {
        logger.error("Error converting file to base64", fileError);
        showToast("error", "Failed to process the uploaded file. Please try again.");
        setIsSaving(false);
        return;
      }
    }

    // ✅ FIXED PAYLOAD - Wrapped in CommodityOptions object, file converted to base64
    const payload = {
      CommodityOptions: {
        ticker,
        isin: securityname,
        t_date: placementdate,
        premium: premiumpaid,
        m_date: expirydate,
        t_o_o: t_o_option?.value ?? "",
        t_o_t: t_o_t?.value ?? "",
        e_t: e_t?.value ?? "",
        o_s: optionstyle?.value ?? "",
        r_no: bankadviserefno,
        quantity: quantity, // Keep as string to match example format
        b_notes: banknotes,
        price: strikeprice, // Keep as string to match example format
        t_price: spotprice,
        p_date: optionstartdate,
        amount: amount,
        commission: commission,
        b_1: chargesandfees,
        b_2: federalturnovertax,
        p_currency: p_currency?.value ?? "",
        bank_id: bank?.value ?? "",
        a_class: 1430,
        a_type: 1435,
        remarks,
        purpose: description,
        r_m: relationshipmanager,
        r_link: fileBase64, // Base64 encoded file string
        knock_ft: "",
        knock: knockamount,
        knock_t: knockT,
        duration: "",
        duration_other: "",
      },
    };

    logger.api("Payload", payload);

    try {
      const url = isEditing && editId
        ? `/api/commodity/derivatives/option/update?id=${encodeURIComponent(editId)}`
        : "/api/commodity/derivatives/option/create";
      const method = isEditing ? "PUT" : "POST";
      
      const response = await fetch(url, {
        method,
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });

      logger.api("API Response status", { status: response.status });

      if (!response.ok) {
        const errorBody = await response.text();
        logger.error("API Error", undefined, { errorText: errorBody, status: response.status });
        throw new Error(
          `Stock Options create failed with status ${response.status} (${response.statusText}): ${errorBody || "No response body"}`
        );
      }

      const result = await response.json();
      logger.api("API Response", result);
      const isSuccess = result?.success === true || result?.status === "success";

      if (isSuccess) {
        showToast("success", isEditing ? "Commodity Options updated successfully!" : "Commodity Options saved successfully!");
        if (!isEditing) {
          resetForm();
        }

      } else {
        const errorMessage =
          typeof result?.message === "string"
            ? result.message
            : "Unexpected response received from the server.";
        showToast("error", errorMessage);
        logger.error("Unexpected API response", undefined, { result });
      }
    } catch (error) {
      logger.error("Error submitting form", error);
      const fallbackMessage =
        error instanceof Error && error.message ? error.message : "Failed to save Stock Options";
      showToast("error", fallbackMessage);
    } finally {
      setIsSaving(false);
    }
  }, [
    validateForm,
    setErrors,
    showToast,
    selectedFile,
    ticker,
    securityname,
    placementdate,
    premiumpaid,
    expirydate,
    t_o_option,
    t_o_t,
    e_t,
    optionstyle,
    bankadviserefno,
    quantity,
    banknotes,
    strikeprice,
    spotprice,
    optionstartdate,
    amount,
    commission,
    chargesandfees,
    federalturnovertax,
    p_currency,
    bank,
    remarks,
    description,
    relationshipmanager,
    knockamount,
    knockT,
    isEditing,
    editId,
    resetForm,
  ]);

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

  const breadcrumbs = useMemo(
    () => [
      { label: "Home", href: "/" },
      { label: "Options", href: "/commodity/derivative" },
      { label: pageTitle },
    ],
    [pageTitle]
  );

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

  return (
    <>
      <ToastComponent toast={toast} />
      <LoadingOverlay isLoading={loadingExisting} message="Loading commodity option data..." />
      <div className="container mx-auto mt-6">
        <div className="bg-white rounded-lg shadow-md border-0">
          <FormSectionHeading
            title={isEditing ? "Update Commodity Options" : "Commodity Options Information"}
            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 sm:grid-cols-4 gap-6">

          {/* 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}
          />

          {/* Placement Date */}
          <PlacementDatePicker
            placementdate={placementdate}
            setplacementdate={setplacementdate}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
            formatDateToString={formatDateToString}
          />

          {/* Premium Paid / Received */}
          <PremiumPaidInput
            premiumpaid={premiumpaid}
            setpremiumpaid={setpremiumpaid}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

          {/* Expiration Date */}
          <ExpirationDateInput
            expirydate={expirydate}
            setexpirydate={setexpirydate}
            formatDateToString={formatDateToString}
          />

          {/* Type of Option */}
          <OptionTypeSelect
            t_o_option={t_o_option}
            sett_o_option={sett_o_option}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

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

          {/* Option Style */}
          <OptionStyleSelect
            optionstyle={optionstyle}
            setoptionstyle={setoptionstyle}
          />

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

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

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

          {/* Strike Price */}
          <StrikePriceInput
            strikeprice={strikeprice}
            setstrikeprice={setstrikeprice}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

          {/* Spot Price */}
          <SpotRateInput
            spotrate={spotprice}
            setspotrate={setspotprice}
            clearError={clearError}
            errors={errors}
            handleFieldBlur={handleFieldBlur}
            validateField={validateField}
          />

          {/* Option Start Date */}
          <OptionStartDateInput
            optionstartdate={optionstartdate}
            setoptionstartdate={setoptionstartdate}
            formatDateToString={formatDateToString}
          />

          {/* Max Exposure */}
          <MaxExposureInput
            maxexposure={maxexposure}
          />

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

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

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

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

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

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

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

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

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

          {/* Knock Amount */}
          <KnockAmountWithSelect
            knockamount={knockamount}
            setknockamount={setknockamount}
            knockList={knockList}
            setKnockList={setKnockList}
          />

          {/* Knock Type Radio */}
          <KnockTypeToggle
            knockT={knockT}
            setKnockT={setKnockT}
          />
        </div>

        <div className="pb-10">
          {/* Spacing for FloatingFooter */}
        </div>
      </form>
    </div>
  </div>
      </div>
      {showBankModal && (
        <BankModal isOpen={showBankModal} onClose={handleCloseBankModal} />
      )}
      <FloatingFooter
        data={footerData}
        onSave={handleSave}
        isSaving={isSaving || loadingExisting}
        saveLabel={isEditing ? "Update" : "Save"}
        savingLabel={isEditing ? "Updating..." : "Saving..."}
      />
    </>
  );
}

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