"use client";

import * as React from "react";

import { zodResolver } from "@hookform/resolvers/zod";
import {
  Building2,
  CalendarDays,
  CircleDollarSign,
  ClipboardList,
  Layers3,
  StickyNote,
} from "lucide-react";
import { FormProvider, useForm, useFormContext, useWatch, type Control } from "react-hook-form";

import type { FilterOption } from "@/app/customer/_lib/customer-asset-filter-options";
import type { LoadStockFormOptionsClient } from "@/app/customer/[tenant]/stock/_lib/stock-api";
import {
  EMPTY_BOND_FORM_OPTIONS,
  type BondFormOptions,
} from "@/app/customer/[tenant]/bond/_lib/bond-form-options";
import { bondFieldLabels, stockFieldLabels, transactionFieldLabels } from "@/components/form/common/field-labels";
import { formGridClass, formSpanFull } from "@/components/form/common/form-layout";
import { DateField } from "@/components/form/fields/date-field";
import { NumberField } from "@/components/form/fields/number-field";
import { SelectField } from "@/components/form/fields/select-field";
import { TextAreaField } from "@/components/form/fields/text-area-field";
import { TextField } from "@/components/form/fields/text-field";
import {
  bondFundsTransactionFormSchema,
  bondTransactionFormSchema,
  defaultBondFormValues,
  defaultBondFundsFormValues,
  type BondFormValues,
  type BondFundsFormValues,
} from "@/components/form/schemas/bond-transaction-schema";

import { TransactionFormSection } from "./form-section";
import { TransactionAmountSummarySidebar } from "./transaction-form-summary";

const MATURITY_EXECUTION_TYPE = "1477";

const KNOCK_TYPE_OPTIONS = [
  { value: "", label: "Percentage" },
  { value: "1", label: "Value" },
];

type BondTransactionFormProps = {
  formId: string;
  variant?: "bond" | "bond-funds";
  initialValues?: BondFormValues | BondFundsFormValues;
  onSubmit?: (values: BondFormValues | BondFundsFormValues) => void;
  loadFormOptions: LoadStockFormOptionsClient;
};

function toSelectOptions(options: FilterOption[]) {
  return options.map((option) => ({ value: option.value, label: option.label }));
}

function AssetClassWatcher({ onChange }: { onChange: (assetClassId: string) => void }) {
  const { control } = useFormContext<BondFormValues>();
  const aClass = useWatch({ control, name: "a_class" });
  const previous = React.useRef<string | null>(null);

  React.useEffect(() => {
    const next = aClass?.trim() || "";
    if (!next || previous.current === next) return;
    previous.current = next;
    onChange(next);
  }, [aClass, onChange]);

  return null;
}

export function BondTransactionForm({
  formId,
  variant = "bond",
  initialValues,
  onSubmit,
  loadFormOptions,
}: BondTransactionFormProps) {
  const isBond = variant === "bond";
  const schema = isBond ? bondTransactionFormSchema : bondFundsTransactionFormSchema;
  const defaults = isBond ? defaultBondFormValues : defaultBondFundsFormValues;

  const [formOptions, setFormOptions] = React.useState<BondFormOptions>(EMPTY_BOND_FORM_OPTIONS);
  const [optionsError, setOptionsError] = React.useState<string | null>(null);
  const [loadingOptions, setLoadingOptions] = React.useState(true);

  const form = useForm<BondFormValues | BondFundsFormValues>({
    resolver: zodResolver(schema),
    defaultValues: initialValues ?? defaults,
    mode: "onBlur",
  });

  React.useEffect(() => {
    form.reset(initialValues ?? defaults);
  }, [defaults, form, initialValues]);

  React.useEffect(() => {
    let cancelled = false;
    setLoadingOptions(true);
    setOptionsError(null);

    void loadFormOptions()
      .then(({ formOptions: options, defaults: serverDefaults }) => {
        if (cancelled) return;
        setFormOptions(options);
        if (!initialValues) {
          const patch: Partial<BondFormValues> = {};
          if (serverDefaults?.a_class != null) patch.a_class = String(serverDefaults.a_class);
          if (serverDefaults?.a_type != null) patch.a_type = String(serverDefaults.a_type);
          if (serverDefaults?.e_t != null) patch.execution_type = String(serverDefaults.e_t);
          if (serverDefaults?.t_o_t != null) patch.transaction = String(serverDefaults.t_o_t);
          if (Object.keys(patch).length > 0) {
            form.reset({ ...defaults, ...form.getValues(), ...patch });
          }
        }
      })
      .catch((error) => {
        if (cancelled) return;
        setOptionsError(error instanceof Error ? error.message : "Could not load form options.");
      })
      .finally(() => {
        if (!cancelled) setLoadingOptions(false);
      });

    return () => {
      cancelled = true;
    };
  }, [defaults, form, initialValues, loadFormOptions]);

  const control = form.control as Control<BondFormValues>;
  const executionType = useWatch({ control: form.control, name: "execution_type" });
  const showMaturityDate = executionType === MATURITY_EXECUTION_TYPE;
  const amountLabel =
    executionType === MATURITY_EXECUTION_TYPE ? "Max Exposure" : transactionFieldLabels.amount;

  const reloadAssetTypes = React.useCallback(
    async (assetClassId: string) => {
      try {
        const { formOptions: next } = await loadFormOptions(assetClassId);
        setFormOptions((prev) => ({
          ...prev,
          assetTypes: next.assetTypes,
          assetClasses: next.assetClasses.length ? next.assetClasses : prev.assetClasses,
        }));
      } catch {
        // Keep existing options.
      }
    },
    [loadFormOptions],
  );

  return (
    <FormProvider {...form}>
      <form
        id={formId}
        noValidate
        onSubmit={form.handleSubmit((values) => onSubmit?.(values))}
        className="w-full min-w-0"
      >
        {loadingOptions ? (
          <p className="mb-4 text-muted-foreground text-sm">Loading dropdown options…</p>
        ) : null}
        {optionsError ? <p className="mb-4 text-destructive text-sm">{optionsError}</p> : null}

        <div className="grid w-full min-w-0 grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_18rem] xl:gap-8">
          <div className="flex min-w-0 flex-col gap-5 lg:gap-6">
            <TransactionFormSection
              title="Transaction & order"
              description="Trade date, type of transaction, execution, reference, and quantity."
              icon={<ClipboardList className="size-4" />}
              contentClassName={formGridClass}
            >
              <DateField control={control} name="t_date" label={transactionFieldLabels.t_date} />
              <SelectField
                control={form.control}
                name="transaction"
                label={stockFieldLabels.transaction}
                options={toSelectOptions(formOptions.transactionTypes)}
                searchable
                searchPlaceholder="Search transaction type…"
              />
              <SelectField
                control={form.control}
                name="execution_type"
                label={stockFieldLabels.execution_type}
                options={toSelectOptions(formOptions.executionTypes)}
                searchable
                searchPlaceholder="Search execution type…"
              />
              <TextField control={control} name="r_no" label={transactionFieldLabels.r_no} />
              <NumberField
                control={control}
                name="quantity"
                label={transactionFieldLabels.quantity}
                step="0.0001"
              />
              {isBond ? (
                <DateField control={control} name="m_date" label={transactionFieldLabels.m_date} />
              ) : showMaturityDate ? (
                <DateField control={form.control} name="m_date" label={transactionFieldLabels.m_date} />
              ) : null}
              {isBond ? (
                <>
                  <TextField control={control} name="knock" label={bondFieldLabels.knock} />
                  <SelectField
                    control={control}
                    name="knock_t"
                    label={bondFieldLabels.knock_type}
                    options={KNOCK_TYPE_OPTIONS}
                  />
                </>
              ) : null}
            </TransactionFormSection>

            <TransactionFormSection
              title="Security & pricing"
              description="Ticker, ISIN, price, effective date, and bank notes."
              icon={<Layers3 className="size-4" />}
              contentClassName={formGridClass}
            >
              <TextField control={control} name="ticker" label={transactionFieldLabels.ticker} />
              <TextField control={control} name="isin" label={transactionFieldLabels.isin} />
              <NumberField control={control} name="price" label={transactionFieldLabels.price} />
              {!isBond ? (
                <DateField control={control} name="p_date" label={transactionFieldLabels.p_date} />
              ) : null}
              <NumberField control={control} name="amount" label={amountLabel} />
              <NumberField control={control} name="t_price" label={transactionFieldLabels.t_price} />
              <TextAreaField
                control={control}
                name="b_notes"
                label={transactionFieldLabels.b_notes}
                className={formSpanFull}
              />
            </TransactionFormSection>

            <TransactionFormSection
              title="Fees & currency"
              description="Commission, charges, tax, and settlement currency."
              icon={<CircleDollarSign className="size-4" />}
              contentClassName={formGridClass}
            >
              <NumberField control={control} name="commission" label={transactionFieldLabels.commission} />
              <TextField control={control} name="b_1" label={transactionFieldLabels.b_1} />
              <TextField control={control} name="b_2" label={transactionFieldLabels.b_2} />
              <SelectField
                control={control}
                name="p_currency"
                label={transactionFieldLabels.p_currency}
                options={toSelectOptions(formOptions.currencies)}
                searchable
                searchPlaceholder="Search currency…"
              />
            </TransactionFormSection>

            <TransactionFormSection
              title="Classification & bank"
              description="Asset type, bank holder, and relationship details."
              icon={<Building2 className="size-4" />}
              contentClassName={formGridClass}
            >
              <div className="hidden">
                <SelectField
                  control={control}
                  name="a_class"
                  label={transactionFieldLabels.a_class}
                  options={toSelectOptions(formOptions.assetClasses)}
                />
              </div>
              <SelectField
                control={control}
                name="a_type"
                label={transactionFieldLabels.a_type}
                options={toSelectOptions(formOptions.assetTypes)}
                searchable
                searchPlaceholder="Search asset type…"
              />
              {isBond ? (
                <TextField control={control} name="duration" label={bondFieldLabels.duration} />
              ) : null}
              <SelectField
                control={control}
                name="bank"
                label={transactionFieldLabels.bank}
                options={toSelectOptions(formOptions.banks)}
                searchable
                searchPlaceholder="Search bank…"
              />
              <TextField control={control} name="r_m" label={transactionFieldLabels.r_m} />
              <TextField control={control} name="r_link" label={transactionFieldLabels.r_link} />
            </TransactionFormSection>

            {isBond ? (
              <TransactionFormSection
                title="Call dates"
                description="Optional callable bond dates."
                icon={<CalendarDays className="size-4" />}
                contentClassName={formGridClass}
              >
                <DateField control={control} name="c_date" label={bondFieldLabels.c_date} />
                <DateField control={control} name="c_date2" label={bondFieldLabels.c_date2} />
                <DateField control={control} name="c_date3" label={bondFieldLabels.c_date3} />
              </TransactionFormSection>
            ) : null}

            <TransactionFormSection
              title="Notes"
              description="Remarks and purpose."
              icon={<StickyNote className="size-4" />}
              contentClassName={formGridClass}
            >
              <TextAreaField
                control={control}
                name="remarks"
                label={transactionFieldLabels.remarks}
                className={formSpanFull}
              />
              <TextAreaField
                control={control}
                name="purpose"
                label={transactionFieldLabels.purpose}
                className={formSpanFull}
              />
            </TransactionFormSection>

            <AssetClassWatcher onChange={reloadAssetTypes} />
          </div>

          <TransactionAmountSummarySidebar
            formOptions={formOptions}
            showEffectiveDate={!isBond}
          />
        </div>
      </form>
    </FormProvider>
  );
}
