"use client";

import * as React from "react";

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

import { withServerValidationErrors } from "@/app/customer/_lib/apply-yii-validation-errors";
import type { StockChildFieldMeta } from "@/app/customer/[tenant]/stock/_lib/stock-child-types";
import {
  EMPTY_STOCK_ACCUMULATOR_FORM_OPTIONS,
  mapStockAccumulatorFormOptions,
  type StockAccumulatorFormOptions,
} from "@/app/customer/[tenant]/stock/_lib/stock-child-form-options";
import { 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 { KnockAmountField } from "@/components/form/fields/knock-amount-field";
import { NumberField } from "@/components/form/fields/number-field";
import { ReferenceLinkField } from "@/components/form/fields/reference-link-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 {
  buildStockAccumulatorFormSchema,
  defaultStockAccumulatorFormValues,
  type StockAccumulatorFormValues,
} from "@/components/form/schemas/stock-accumulator-schema";
import { TransactionAmountSummarySidebar } from "@/components/form/transaction-workspace/transaction-form-summary";
import { cn } from "@/lib/utils";

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

const MATURITY_EXECUTION_TYPE = "1477";

const DEFAULT_KNOCK_FT_OPTIONS = [
  { value: "1", label: "Knock In" },
  { value: "2", label: "Knock Out" },
];

type StockAccumulatorTransactionFormProps = {
  formId: string;
  initialValues?: StockAccumulatorFormValues;
  formOptionsRaw?: Record<string, Record<string, string>>;
  fieldMeta?: StockChildFieldMeta;
  onSubmit?: (values: StockAccumulatorFormValues) => void | Promise<void>;
};

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

function LockedSection({
  locked,
  children,
}: {
  locked: boolean;
  children: React.ReactNode;
}) {
  return (
    <div className={cn("relative w-full min-w-0")}>
      {locked ? <div className="pointer-events-none absolute inset-0 z-10 rounded-lg bg-background/40" aria-hidden /> : null}
      {children}
    </div>
  );
}

function calculateMaturityDate(cDate: string, duration: number, durationOther: string): string {
  if (!cDate.trim() || duration <= 0 || !durationOther.trim()) {
    return "";
  }

  const date = new Date(cDate);
  if (Number.isNaN(date.getTime())) {
    return "";
  }

  const stepDays = Number.parseInt(durationOther, 10);
  if (!Number.isFinite(stepDays) || stepDays <= 0) {
    return "";
  }

  for (let i = 1; i < duration; i++) {
    date.setDate(date.getDate() + stepDays);
  }

  return date.toISOString().slice(0, 10);
}

export function StockAccumulatorTransactionForm({
  formId,
  initialValues,
  formOptionsRaw,
  fieldMeta,
  onSubmit,
}: StockAccumulatorTransactionFormProps) {
  const [formOptions, setFormOptions] = React.useState<StockAccumulatorFormOptions>(
    EMPTY_STOCK_ACCUMULATOR_FORM_OPTIONS,
  );

  const lockParent = fieldMeta?.lockParentSection ?? false;
  const requireSecurityFields = !lockParent;

  const resolver = React.useMemo(
    () => zodResolver(buildStockAccumulatorFormSchema(requireSecurityFields)),
    [requireSecurityFields],
  );

  const form = useForm<StockAccumulatorFormValues>({
    resolver,
    defaultValues: { ...defaultStockAccumulatorFormValues, ...initialValues },
    mode: "onBlur",
  });

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

  React.useEffect(() => {
    if (formOptionsRaw) {
      setFormOptions(mapStockAccumulatorFormOptions(formOptionsRaw));
    }
  }, [formOptionsRaw]);

  const duration = useWatch({ control: form.control, name: "duration" });
  const durationOther = useWatch({ control: form.control, name: "duration_other" });
  const cDate = useWatch({ control: form.control, name: "c_date" });
  const executionType = useWatch({ control: form.control, name: "execution_type" });

  React.useEffect(() => {
    const maturityDate = calculateMaturityDate(cDate ?? "", Number(duration || 0), durationOther ?? "");
    if (maturityDate) {
      form.setValue("m_date", maturityDate, { shouldDirty: true });
    }
  }, [form, cDate, duration, durationOther]);

  const showMaturityDate = executionType === MATURITY_EXECUTION_TYPE;
  const amountLabel =
    executionType === MATURITY_EXECUTION_TYPE ? "Max Exposure" : transactionFieldLabels.amount;
  const knockFtOptions =
    formOptions.knockFtTypes.length > 0 ? formOptions.knockFtTypes : DEFAULT_KNOCK_FT_OPTIONS;

  return (
    <FormProvider {...form}>
      <form
        id={formId}
        className="w-full min-w-0"
        noValidate
        onSubmit={form.handleSubmit(withServerValidationErrors(form.setError, onSubmit))}
      >
        <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">
            <LockedSection locked={lockParent}>
              <TransactionFormSection title="Security" icon={<Layers3 className="size-4" />} contentClassName={formGridClass}>
                {lockParent ? <TextField control={form.control} name="uid" label="Ref. ID" readOnly /> : null}
                <TextField control={form.control} name="ticker" label={transactionFieldLabels.ticker} />
                <TextField control={form.control} name="isin" label={transactionFieldLabels.isin} />
                <TextField control={form.control} name="parent_isin" label="Parent ISIN" />
                <TextField control={form.control} name="parent_isin_name" label="Parent ISIN Name" className={formSpanFull} />
              </TransactionFormSection>
            </LockedSection>

            <TransactionFormSection title="Transaction" icon={<ClipboardList className="size-4" />} contentClassName={formGridClass}>
              <DateField control={form.control} name="t_date" label="Placement Date" />
              <DateField control={form.control} name="o_date" label="Observation Date" />
              <SelectField control={form.control} name="transaction" label="Type of Transaction" options={toSelectOptions(formOptions.transactionTypes)} searchable />
              <SelectField control={form.control} name="execution_type" label={stockFieldLabels.execution_type} options={toSelectOptions(formOptions.executionTypes)} searchable />
              <TextField control={form.control} name="r_no" label={transactionFieldLabels.r_no} />
              <NumberField control={form.control} name="duration" label="No. of Periods" />
              <SelectField control={form.control} name="duration_other" label="Period unit" options={toSelectOptions(formOptions.timePeriods)} />
              <DateField control={form.control} name="c_date" label="Start Date" />
              <SelectField control={form.control} name="accumulator_type" label="Type of Accumulator" options={toSelectOptions(formOptions.accumulatorTypes)} searchable />
              <SelectField control={form.control} name="i_b" label="Accumulator Frequency" options={toSelectOptions(formOptions.interestBase)} />
            </TransactionFormSection>

            <TransactionFormSection title="Pricing" icon={<CircleDollarSign className="size-4" />} contentClassName={formGridClass}>
              <NumberField control={form.control} name="quantity" label="Quantity (Total)" step="0.0001" />
              <TextAreaField control={form.control} name="b_notes" label={transactionFieldLabels.b_notes} className={formSpanFull} />
              <NumberField control={form.control} name="price" label="Strike Price" step="0.0001" />
              <NumberField control={form.control} name="t_price" label="Spot Rate" step="0.0001" />
              <NumberField control={form.control} name="maturity" label="Profit Taking" step="0.0001" />
              <NumberField control={form.control} name="amount" label={amountLabel} readOnly />
              {showMaturityDate ? (
                <DateField control={form.control} name="m_date" label={transactionFieldLabels.m_date} />
              ) : null}
              <NumberField control={form.control} name="commission" label={transactionFieldLabels.commission} />
              <TextField control={form.control} name="b_1" label={transactionFieldLabels.b_1} />
              <TextField control={form.control} name="b_2" label={transactionFieldLabels.b_2} />
              <SelectField control={form.control} name="p_currency" label="Currency (If Different)" options={toSelectOptions(formOptions.currencies)} searchable />
            </TransactionFormSection>

            <TransactionFormSection title="Bank & fees" icon={<Building2 className="size-4" />} contentClassName={formGridClass}>
              <SelectField control={form.control} name="bank" label={transactionFieldLabels.bank} options={toSelectOptions(formOptions.banks)} searchable />
              <TextField control={form.control} name="r_m" label={transactionFieldLabels.r_m} />
              <ReferenceLinkField control={form.control} name="r_link" />
            </TransactionFormSection>

            <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} />
              <KnockAmountField
                control={form.control}
                knockFtName="knock_ft"
                knockName="knock"
                knockTName="knock_t"
                knockFtOptions={knockFtOptions}
              />
            </TransactionFormSection>
          </div>

          <TransactionAmountSummarySidebar
            formOptions={{
              banks: formOptions.banks,
              transactionTypes: formOptions.transactionTypes,
              executionTypes: formOptions.executionTypes,
              currencies: formOptions.currencies,
              assetTypes: [],
            }}
            subheadlineField="isin"
            effectiveDateField="c_date"
            effectiveDateLabel="Start date"
            netMode="add"
            netLabel="Net Exposure"
            useMaturityGrossLabel
          />
        </div>
      </form>
    </FormProvider>
  );
}
