"use client";

import * as React from "react";

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

import type { FilterOption } from "@/app/customer/_lib/customer-asset-filter-options";
import {
  EMPTY_DEPOSIT_FORM_OPTIONS,
  type DepositFormOptions,
} from "@/app/customer/_lib/deposit-form-options";
import { 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 {
  callDepositTransactionFormSchema,
  defaultCallDepositFormValues,
  type CallDepositFormValues,
} from "@/components/form/schemas/call-deposit-transaction-schema";
import { parseAmount } from "@/components/form/transaction-workspace/transaction-form-summary";

import { TransactionFormSection } from "./form-section";
import type { LoadDepositFormOptionsClient } from "./deposit-transaction-form";

type CallDepositTransactionFormProps = {
  formId: string;
  initialValues?: CallDepositFormValues;
  onSubmit?: (values: CallDepositFormValues) => void;
  loadFormOptions: LoadDepositFormOptionsClient;
};

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

export function CallDepositTransactionForm({
  formId,
  initialValues,
  onSubmit,
  loadFormOptions,
}: CallDepositTransactionFormProps) {
  const [formOptions, setFormOptions] = React.useState<DepositFormOptions>(EMPTY_DEPOSIT_FORM_OPTIONS);
  const [optionsError, setOptionsError] = React.useState<string | null>(null);
  const [loadingOptions, setLoadingOptions] = React.useState(true);

  const form = useForm<CallDepositFormValues>({
    resolver: zodResolver(callDepositTransactionFormSchema),
    defaultValues: { ...defaultCallDepositFormValues, ...initialValues },
    mode: "onBlur",
  });

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

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

  const price = useWatch({ control: form.control, name: "price" });
  React.useEffect(() => {
    form.setValue("amount", -Math.abs(parseAmount(price)), { shouldDirty: true });
  }, [form, price]);

  return (
    <FormProvider {...form}>
      <form id={formId} noValidate onSubmit={form.handleSubmit((values) => onSubmit?.(values))}>
        {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="flex flex-col gap-5">
          <TransactionFormSection title="Call deposit" icon={<ClipboardList className="size-4" />} contentClassName={formGridClass}>
            <DateField control={form.control} name="t_date" label="Placement Date" />
            <SelectField control={form.control} name="p_currency" label="Currency" options={toSelectOptions(formOptions.currencies)} searchable />
            <NumberField control={form.control} name="price" label="Amount" step="0.01" />
            <TextField control={form.control} name="r_no" label={transactionFieldLabels.r_no} />
            <NumberField control={form.control} name="i_rate" label="Interest Rate (% p.a.)" step="0.0001" />
            <SelectField control={form.control} name="bank" label={transactionFieldLabels.bank} options={toSelectOptions(formOptions.banks)} searchable />
          </TransactionFormSection>
          <TransactionFormSection title="Fees" icon={<CircleDollarSign className="size-4" />} contentClassName={formGridClass}>
            <NumberField control={form.control} name="commission" label="Transaction Costs" />
            <TextField control={form.control} name="b_1" label="Premium" />
            <TextField control={form.control} name="b_2" label="Tax" />
          </TransactionFormSection>
          <div className="hidden">
            <SelectField control={form.control} name="a_class" label="Asset Class" options={toSelectOptions(formOptions.assetClasses)} />
            <SelectField control={form.control} name="a_type" label="Asset Type" options={toSelectOptions(formOptions.assetTypes)} />
          </div>
          <TransactionFormSection title="Notes" icon={<StickyNote className="size-4" />} contentClassName={formGridClass}>
            <TextAreaField control={form.control} name="remarks" label={transactionFieldLabels.remarks} className={formSpanFull} />
            <TextAreaField control={form.control} name="purpose" label={transactionFieldLabels.purpose} className={formSpanFull} />
            <TextField control={form.control} name="r_link" label={transactionFieldLabels.r_link} className={formSpanFull} />
          </TransactionFormSection>
        </div>
      </form>
    </FormProvider>
  );
}
