import { useCallback, useEffect, useState } from "react";
import SearchableSelect from "@/components/ui/SearchableSelect";
import { TextBox } from "@/components/ui/TextBox";
import DatePicker from "@/components/ui/DatePicker";
import { FileUploader } from "@/components/ui/FileUploader";
import { InterestDividendFormField } from "@/components/validation/FormFields";
import { resolveFileUrl } from "@/components/datatable/liststock/columns";

const normalizeQtyForRef = (value: unknown): string => {
  const text = String(value ?? "").trim();
  const normalized = text.toLowerCase();
  const numeric = Number.parseFloat(text);
  if (text === "" || normalized === "null") return "1";
  if (Number.isFinite(numeric) && numeric <= 0) return "1";
  return text;
};

const normalizeQtyGeneric = (value: unknown): string => {
  const text = String(value ?? "").trim();
  return text.toLowerCase() === "null" ? "" : text;
};

interface InterestDividendFormFieldsProps {
  formData: {
    placementdate: string;
    transactiontype: { label: string; value: string } | null;
    type: { label: string; value: string } | null;
    transactionrefno: { label: string; value: string } | null;
    md: { label: string; value: string } | null;
    bankadviserefno: string;
    commission: string;
    chargesandfees: string;
    federalturnovertax: string;
    quantity: string;
    amount: string;
    total: string;
    ticker: string;
    isin: string;
    bank_id: { label: string; value: string } | null;
    transactionDetails: Array<{ id: string | number; quantity: string }>;
  };
  errors: Partial<Record<InterestDividendFormField, string>>;
  clearError: (field: string) => void;
  handleFieldBlur: (field: InterestDividendFormField, validateField: (field: InterestDividendFormField) => string | undefined) => void;
  validateField: (field: InterestDividendFormField) => string | undefined;
  updateFormData: (updates: Partial<any>) => void;
  formatDateToString: (date: Date) => string;
  handlePlacementDateChange: (date: Date) => void;
  handleTransactionRefChange: (option: { label: string; value: string } | null) => void;
  handleQuantityChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
  handleAmountChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
  setSelectedFile: (file: File | null) => void;
  existingFileUrl?: string;
}

export function InterestDividendFormFields({
  formData,
  errors,
  clearError,
  handleFieldBlur,
  validateField,
  updateFormData,
  formatDateToString,
  handlePlacementDateChange,
  handleTransactionRefChange,
  handleQuantityChange,
  handleAmountChange,
  setSelectedFile,
  existingFileUrl,
}: InterestDividendFormFieldsProps) {
  const isInterestOnSecurity = formData.type?.value === "2";
  const fTypeLabelMap: Record<string, string> = {
    S: "Stock",
    Cd: "Commodity",
    Bd: "Bond",
    Bf: "Bond Fund",
    Hf: "Other Assets",
  };
  const [transactionDetails, setTransactionDetails] = useState<
    Array<{
      id?: string | number | null;
      f_type: string;
      t_date: string;
      uid?: string | null;
      bank_name: string;
      quantity: string;
      purchased: string;
      saled: string;
      price: string;
      amount: string;
    }>
  >([]);
  const [transactionDetailsLoading, setTransactionDetailsLoading] = useState(false);

  const selectedSecurity = formData.isin
    ? {
        label:
          formData.ticker && formData.ticker.trim() !== ""
            ? `${formData.ticker} (${formData.isin})`
            : formData.isin,
        value: formData.isin,
        ticker: formData.ticker,
        isin: formData.isin,
      }
    : null;
  const resolvedExistingUrl = existingFileUrl ? resolveFileUrl({ r_link: existingFileUrl }) : "";

  const fetchTransactionDetails = useCallback(
    async (args: { ticker: string; isin: string; bankId: string; date: string }) => {
      const { ticker, isin, bankId, date } = args;
      if (!ticker.trim() || !isin.trim() || !bankId || !date.trim()) return;

      setTransactionDetailsLoading(true);
      const abortController = new AbortController();
      const timeout = setTimeout(() => abortController.abort(), 10_000);
      try {
        const res = await fetch("/api/cash/fetchinteresttransactiondetails", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            ticker,
            isin,
            bank_id: bankId,
            date,
          }),
          signal: abortController.signal,
        });

        if (!res.ok) return;
        const data = await res.json();
        const items = Array.isArray(data?.items) ? data.items : [];

        setTransactionDetails(
          items.map((it: any) => ({
            id: it?.id ?? null,
            f_type: String(it?.f_type ?? ""),
            t_date: String(it?.t_date ?? ""),
            uid: it?.uid ?? null,
            bank_name: String(it?.bank_name ?? ""),
            quantity: normalizeQtyGeneric(it?.quantity),
            purchased: String(it?.purchased ?? "0"),
            saled: String(it?.saled ?? "0"),
            price: String(it?.price ?? "0"),
            amount: String(it?.amount ?? "0"),
          }))
        );
        updateFormData({
          transactionDetails: items
            .map((it: any) => ({
              id: it?.id,
              quantity: normalizeQtyGeneric(it?.quantity),
            }))
            .filter((it: { id: unknown }) => it.id !== null && it.id !== undefined && String(it.id).trim() !== ""),
        });

        if (data?.quantity !== undefined && data?.quantity !== null) {
          updateFormData({ quantity: normalizeQtyGeneric(data.quantity) });
          clearError("quantity");
        }
      } catch (e) {
        console.error("Transaction details fetch failed", e);
      } finally {
        clearTimeout(timeout);
        setTransactionDetailsLoading(false);
      }
    },
    // `clearError` is re-created on each render in `useFormState`, so excluding it prevents
    // an infinite refetch loop. The closure still works because `setErrors` is stable.
    [updateFormData]
  );

  const fetchTransactionByRef = useCallback(
    async (transactionId: string) => {
      const id = String(transactionId || "").trim();
      if (!id) {
        setTransactionDetails([]);
        updateFormData({ transactionDetails: [] });
        return;
      }

      try {
        const res = await fetch(`/api/stock/${encodeURIComponent(id)}`, {
          method: "GET",
          headers: { "Content-Type": "application/json" },
        });
        if (!res.ok) {
          setTransactionDetails([]);
          updateFormData({ transactionDetails: [] });
          return;
        }

        const json = await res.json();
        const attrs = (json?.data?.attributes ?? json?.data ?? {}) as Record<string, unknown>;

        const bankId = attrs?.bank_id ? String(attrs.bank_id) : "";
        const bankName = attrs?.bank_name ? String(attrs.bank_name) : "";
        const ticker = attrs?.ticker ? String(attrs.ticker) : "";
        const isin = attrs?.isin ? String(attrs.isin) : "";
        const rowQuantity = normalizeQtyForRef(attrs?.quantity);

        setTransactionDetails([
          {
            id: attrs?.id ? String(attrs.id) : id,
            f_type: attrs?.f_type ? String(attrs.f_type) : "",
            t_date: attrs?.t_date ? String(attrs.t_date) : "",
            uid: attrs?.uid ? String(attrs.uid) : null,
            bank_name: bankName,
            quantity: rowQuantity,
            purchased: "0",
            saled: "0",
            price: attrs?.price !== undefined && attrs?.price !== null ? String(attrs.price) : "0",
            amount: attrs?.amount !== undefined && attrs?.amount !== null ? String(attrs.amount) : "0",
          },
        ]);

        updateFormData({
          transactionDetails: [{ id, quantity: rowQuantity }],
          ticker,
          isin,
          bank_id: bankId ? { value: bankId, label: bankName || bankId } : null,
          quantity: rowQuantity,
        });
      } catch (e) {
        console.error("TransactionRef->details fetch failed", e);
        setTransactionDetails([]);
        updateFormData({ transactionDetails: [] });
      }
    },
    [updateFormData]
  );

  // Edit mode: if ticker/isin/bank/date already exist, fetch the legacy breakdown automatically.
  useEffect(() => {
    if (!isInterestOnSecurity) {
      return;
    }

    const bankId = formData.bank_id?.value;
    if (!bankId) {
      setTransactionDetails([]);
      updateFormData({ transactionDetails: [] });
      return;
    }
    if (!formData.ticker?.trim() || !formData.isin?.trim() || !formData.placementdate?.trim()) {
      setTransactionDetails([]);
      updateFormData({ transactionDetails: [] });
      return;
    }

    fetchTransactionDetails({
      ticker: formData.ticker,
      isin: formData.isin,
      bankId,
      date: formData.placementdate,
    });
  }, [
    fetchTransactionDetails,
    isInterestOnSecurity,
    formData.bank_id?.value,
    formData.ticker,
    formData.isin,
    formData.placementdate,
  ]);

  // For "Interest On Transaction", load details table from selected transaction ref.
  useEffect(() => {
    if (isInterestOnSecurity) return;
    const transactionId = formData.transactionrefno?.value;
    if (!transactionId) {
      setTransactionDetails([]);
      updateFormData({ transactionDetails: [] });
      return;
    }
    fetchTransactionByRef(String(transactionId));
  }, [isInterestOnSecurity, formData.transactionrefno?.value, fetchTransactionByRef, updateFormData]);

  return (
    <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
      {/* Placement Date */}
      <div className="group">
        <DatePicker
          label="Placement Date"
          value={formData.placementdate}
          onChange={handlePlacementDateChange}
          error={errors.placementdate}
          onBlur={() => handleFieldBlur("placementdate", validateField)}
          className="text-sm transition-all duration-200 group-hover:shadow-md"
        />
      </div>

      {/* Transaction Type */}
<div className="group">
  <SearchableSelect
    label="Transaction Type"
    apiUrl="/api/searchabledropdown/dplist"
    value={formData.transactiontype}
    onChange={(option) => {
      updateFormData({ transactiontype: option });
      clearError("transactiontype");
    }}
    placeholder="Select transaction type..."
    error={errors.transactiontype}
  />
</div>

{/* Type */}
<div className="group">
  <SearchableSelect
    label="Type"
    apiUrl="/api/searchabledropdown/dtypelist"
    value={formData.type}
    onChange={(option) => {
      updateFormData({
        type: option,
        transactionrefno: null,
        ticker: "",
        isin: "",
        bank_id: null,
        quantity: "",
        transactionDetails: [],
        md: option?.value === "2" ? { label: "Per Share", value: "2" } : formData.md,
      });
      clearError("type");
              clearError("quantity");
      setTransactionDetails([]);
    }}
    placeholder="Select type..."
    error={errors.type}
  />
</div>

      {/* d_type == '1': Transaction Ref. # */}
      {!isInterestOnSecurity && (
        <div className="group">
          <SearchableSelect
            label="Transaction Ref. #"
            apiUrl="/api/searchabledropdown/transactionlist"
            value={formData.transactionrefno}
            onChange={async (option) => {
              updateFormData({ transactionrefno: option });
              clearError("transactionRef");

              if (!option?.value) {
                updateFormData({ quantity: "" });
                clearError("quantity");
                return;
              }

              // Legacy behavior: quantity is auto-filled when transaction ref changes.
              try {
                const res = await fetch("/api/cash/fetchtransactionquantity", {
                  method: "POST",
                  headers: { "Content-Type": "application/json" },
                  body: JSON.stringify({
                    id: option.value,
                    date: formData.placementdate,
                  }),
                });

                if (!res.ok) return;
                const data = await res.json();
                if (data?.quantity !== undefined && data?.quantity !== null) {
                  updateFormData({ quantity: normalizeQtyForRef(data.quantity) });
                  clearError("quantity");
                }

                // Also populate transaction data table/details for d_type=1.
                await fetchTransactionByRef(String(option.value));
              } catch (e) {
                console.error("TransactionRef->quantity autofill failed", e);
              }
            }}
            placeholder="Select transaction ref..."
            onBlur={() => handleFieldBlur("transactionRef", validateField)}
            error={errors.transactionRef}
            serverSideSearch={true}  

          />
        </div>
      )}

     {/* d_type == '2': Ticker + ISIN (single autocomplete) */}
     {isInterestOnSecurity && (
       <div className="group">
         <SearchableSelect
           label="Ticker / Security"
           apiUrl="/api/searchabledropdown/autocomplete_stockname_by_name"
           value={selectedSecurity}
             onChange={async (option) => {
               const ticker = option?.ticker ?? "";
               const isin = option?.isin ?? "";

               updateFormData({ ticker, isin });
               clearError("ticker");
               clearError("isin");

               // Legacy behavior: if a bank is already selected, changing ticker/isin
               // should immediately re-fetch and auto-fill quantity.
              if (!formData.bank_id?.value) {
                setTransactionDetails([]);
                updateFormData({ transactionDetails: [] });
                return;
              }
              if (!ticker.trim() || !isin.trim()) {
                setTransactionDetails([]);
                updateFormData({ transactionDetails: [] });
                return;
              }
              if (!formData.placementdate?.trim()) {
                setTransactionDetails([]);
                updateFormData({ transactionDetails: [] });
                return;
              }

               try {
                 const res = await fetch("/api/cash/fetchinterestquantity", {
                   method: "POST",
                   headers: { "Content-Type": "application/json" },
                   body: JSON.stringify({
                     ticker,
                     isin,
                     bank_id: formData.bank_id.value,
                     date: formData.placementdate,
                   }),
                 });

                 if (!res.ok) return;
                 const data = await res.json();
                 if (data?.quantity !== undefined && data?.quantity !== null) {
                   updateFormData({ quantity: normalizeQtyGeneric(data.quantity) });
                   clearError("quantity");
                 }

                // Also fetch the legacy "transactions table" breakdown
                await fetchTransactionDetails({
                  ticker,
                  isin,
                  bankId: formData.bank_id.value,
                  date: formData.placementdate,
                });
               } catch (e) {
                 console.error("Ticker/ISIN->quantity autofill failed", e);
               }
             }}
           placeholder="Type ticker or ISIN..."
           serverSideSearch={true}
           error={errors.ticker ?? errors.isin}
           onBlur={() => {
             handleFieldBlur("ticker", validateField);
             handleFieldBlur("isin", validateField);
           }}
         />
       </div>
     )}

{/* d_type == '2': Bank */}
{isInterestOnSecurity && (
  <div className="group">
    <SearchableSelect
      label="Bank"
      apiUrl="/api/searchabledropdown/banklist"
      value={formData.bank_id}
      onChange={async (option) => {
        updateFormData({ bank_id: option });
        clearError("bank_id");

        // Legacy behavior: when bank changes in Interest/Dividend type=2,
        // backend auto-fills `quantity` based on ticker + isin + bank + date.
        if (!option?.value) {
          setTransactionDetails([]);
          updateFormData({ transactionDetails: [] });
          return;
        }
        if (!formData.ticker?.trim() || !formData.isin?.trim()) {
          setTransactionDetails([]);
          updateFormData({ transactionDetails: [] });
          return;
        }
        if (!formData.placementdate?.trim()) {
          setTransactionDetails([]);
          updateFormData({ transactionDetails: [] });
          return;
        }

        try {
          const res = await fetch("/api/cash/fetchinterestquantity", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              ticker: formData.ticker,
              isin: formData.isin,
              bank_id: option.value,
              date: formData.placementdate,
            }),
          });

          if (!res.ok) return;
          const data = await res.json();
          if (data?.quantity !== undefined && data?.quantity !== null) {
            updateFormData({ quantity: normalizeQtyGeneric(data.quantity) });
            clearError("quantity");
          }

          // Also fetch the legacy "transactions table" breakdown
          await fetchTransactionDetails({
            ticker: formData.ticker,
            isin: formData.isin,
            bankId: String(option.value),
            date: formData.placementdate,
          });
        } catch (e) {
          // Non-blocking: let user manually enter quantity if fetch fails.
          console.error("Bank->quantity autofill failed", e);
        }
      }}
      placeholder="Select bank..."
      error={errors.bank_id}
    />
  </div>
)}

      {/* Transactions Breakdown (legacy table) */}
      {(isInterestOnSecurity || (!isInterestOnSecurity && !!formData.transactionrefno?.value)) && (
        <div className="group sm:col-span-2 lg:col-span-4">
          <div className="mb-2 text-sm font-semibold text-slate-700">Transactions</div>
          {transactionDetailsLoading ? (
            <div className="text-sm text-slate-500">Loading transactions…</div>
          ) : transactionDetails.length === 0 ? (
            <div className="text-sm text-slate-500">No transactions found.</div>
          ) : (
            <div className="overflow-x-auto rounded-md border border-slate-200 bg-white">
              <table className="min-w-full text-left text-xs">
                <thead className="bg-slate-50 text-slate-600">
                  <tr>
                    <th className="px-3 py-2">Date</th>
                    <th className="px-3 py-2">Reference #</th>
                    <th className="px-3 py-2">Quantity</th>
                    <th className="px-3 py-2">Price</th>
                  </tr>
                </thead>
                <tbody>
                  {transactionDetails.map((row, idx) => (
                    <tr key={`${row.uid ?? "row"}-${idx}`} className="border-t border-slate-200">
                      <td className="px-3 py-2">
                        <div className="font-medium text-slate-900">
                          {fTypeLabelMap[row.f_type] ?? row.f_type}
                        </div>
                        <div className="text-slate-600">{row.t_date}</div>
                        {row.bank_name ? (
                          <div className="text-slate-500">
                            <span className="italic">Bank:</span> {row.bank_name}
                          </div>
                        ) : null}
                      </td>
                      <td className="px-3 py-2 text-slate-900">{row.uid ?? ""}</td>
                      <td className="px-3 py-2">
                        <div className="font-medium text-slate-900">{row.quantity}</div>
                        <div className="text-slate-500">
                          <div>
                            <span className="italic">Purchased:</span> {row.purchased}
                          </div>
                          <div>
                            <span className="italic">Sold:</span> {row.saled}
                          </div>
                        </div>
                      </td>
                      <td className="px-3 py-2 text-slate-900">{row.price}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      )}

      {/* Bank Advice Ref No */}
      <div className="group">
        <TextBox
          label="Bank Advice Ref No"
          placeholder="Enter reference number"
          className="text-sm transition-all duration-200 group-hover:shadow-md"
          value={formData.bankadviserefno}
          onChange={(e) => updateFormData({ bankadviserefno: e.target.value })}
        />
      </div>

      {/* Commission */}
      <div className="group">
        <TextBox
          label="Commission"
          placeholder="Enter commission amount"
          type="number"
          className="text-sm transition-all duration-200 group-hover:shadow-md"
          value={formData.commission}
          onChange={(e) => updateFormData({ commission: e.target.value })}
        />
      </div>

      {/* Charges and Fees Abroad */}
      <div className="group">
        <TextBox
          label="Charges and Fees Abroad"
          placeholder="Enter charges amount"
          type="number"
          className="text-sm transition-all duration-200 group-hover:shadow-md"
          value={formData.chargesandfees}
          onChange={(e) => updateFormData({ chargesandfees: e.target.value })}
        />
      </div>

      {/* Federal Turnover Tax */}
      <div className="group">
        <TextBox
          label="Federal Turnover Tax"
          placeholder="Enter tax amount"
          type="number"
          className="text-sm transition-all duration-200 group-hover:shadow-md"
          value={formData.federalturnovertax}
          onChange={(e) => updateFormData({ federalturnovertax: e.target.value })}
        />
      </div>

      {/* Quantity */}
      <div className="group">
        <TextBox
          label="Quantity (No. of Shares)"
          placeholder="Enter quantity"
          type="number"
          className="text-sm transition-all duration-200 group-hover:shadow-md"
          value={normalizeQtyGeneric(formData.quantity)}
          readOnly={true}
          disabled={true}
          onChange={handleQuantityChange}
          onBlur={() => handleFieldBlur("quantity", validateField)}
          error={errors.quantity}
        />
      </div>

      {/* Amount */}
      <div className="group">
        <TextBox
          label="Amount"
          placeholder={
            formData.md?.label?.toLowerCase().includes("per") ? "Enter amount per share" : "Enter total amount"
          }
          type="number"
          className="text-sm transition-all duration-200 group-hover:shadow-md"
          value={formData.amount}
          onChange={handleAmountChange}
          onBlur={() => handleFieldBlur("amount", validateField)}
          error={errors.amount}
        />
      </div>

      {/* MD */}
      <div className="group">
        <SearchableSelect
          label="MD"
          apiUrl="/api/searchabledropdown/mdlist"
          value={formData.md}
          onChange={(option) => updateFormData({ md: option })}
          placeholder="Select MD..."
          error={errors.md}

        />
      </div>

      {/* Net Amount */}
      <div className="group">
        <TextBox
          label="Net Amount"
          placeholder="Enter net amount"
          type="number"
          className="text-sm transition-all duration-200 group-hover:shadow-md"
          value={formData.total}
          readOnly={true}
        />
      </div>

      {/* File Upload */}
      <div className="group sm:col-span-2 lg:col-span-4">
        <div className="relative p-6 rounded-lg bg-gradient-to-br from-slate-50/80 to-white border-2 border-dashed border-slate-200 hover:border-[#428B4D]/40 transition-all duration-300">
          {resolvedExistingUrl ? (
            <div className="mb-4">
              <a
                href={resolvedExistingUrl}
                target="_blank"
                rel="noopener noreferrer"
                className="inline-flex items-center rounded-lg border border-[#428B4D]/40 bg-white px-3 py-1.5 text-xs font-semibold text-[#428B4D] transition hover:border-[#428B4D] hover:bg-[#428B4D] hover:text-white"
              >
                View Current Document
              </a>
            </div>
          ) : null}
          <FileUploader
            label="Upload Document"
            onFileChange={setSelectedFile}
            maxSizeMB={1}
            allowedTypes={["application/pdf", "image/png", "image/jpg", "image/jpeg"]}
          />
        </div>
      </div>
    </div>
  );
}