"use client";

import { isApiSuccess } from "@/lib/api-messages";
import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { zodResolver } from "@hookform/resolvers/zod";
import { Layers, Plus } from "lucide-react";
import { Controller, useForm } from "react-hook-form";
import { toast } from "sonner";

import {
  FormPageHeader,
  FormPanel,
  FormSaveBar,
} from "@/app/dashboard/_components/form";
import { FormField } from "@/components/form/form-field";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { SettingsSelect } from "@/components/settings/ui/settings-select";
import { requestDashboardApi } from "@/lib/dashboard-api-client";

import {
  CREATE_HREF,
  LIST_HREF,
  YES_NO_OPTIONS,
} from "../constants";
import type { IsinAssetRow } from "../schema";
import {
  isinAssetFormSchema,
  type IsinAssetFormValues,
} from "./schema";

type Props = {
  mode: "create" | "update";
  initialRow?: IsinAssetRow;
};

const defaults: IsinAssetFormValues = {
  isin: "",
  assetClassCode: "",
  inPortfolio: "yes",
};

function rowToValues(row: IsinAssetRow): IsinAssetFormValues {
  return {
    isin: row.isin,
    assetClassCode: row.assetClassCode,
    inPortfolio: row.inPortfolio,
  };
}

export function IsinAssetsForm({ mode, initialRow }: Props) {
  const router = useRouter();
  const isUpdate = mode === "update";
  const [isSaving, setIsSaving] = useState(false);

  const defaultValues = useMemo(
    () => (initialRow ? rowToValues(initialRow) : defaults),
    [initialRow],
  );

  const form = useForm<IsinAssetFormValues>({
    resolver: zodResolver(isinAssetFormSchema),
    defaultValues,
  });

  const {
    control,
    register,
    handleSubmit,
    formState: { errors },
  } = form;

  useEffect(() => {
    form.reset(initialRow ? rowToValues(initialRow) : defaults);
  }, [form, initialRow]);

  const onSubmit = handleSubmit(async (values) => {
    setIsSaving(true);
    try {
      const url = isUpdate
        ? "/dashboard/master-table/isin-assets/update"
        : "/dashboard/master-table/isin-assets/create/submit";

      const body = isUpdate
        ? {
            id: initialRow?.id ?? initialRow?.isin,
            ...values,
          }
        : values;

      const data = await requestDashboardApi<{ status?: string; message?: string }>({
        url,
        method: "POST",
        body,
        fallbackError: `ISIN asset could not be ${isUpdate ? "updated" : "created"}.`,
        validate: (payload) => isApiSuccess(payload),
      });

      toast.success(
        data.message ?? `ISIN asset ${isUpdate ? "updated" : "created"}.`,
      );
      router.push(LIST_HREF);
      router.refresh();
    } catch (error) {
      toast.error(
        error instanceof Error
          ? error.message
          : `ISIN asset could not be ${isUpdate ? "updated" : "created"}.`,
      );
    } finally {
      setIsSaving(false);
    }
  });

  return (
    <form onSubmit={(e) => void onSubmit(e)} className="pb-4">
      <FormPageHeader
        backHref={LIST_HREF}
        breadcrumb={[
          { label: "Master Table", href: LIST_HREF },
          { label: "ISIN Assets", href: LIST_HREF },
          { label: isUpdate ? "Update" : "Create new" },
        ]}
        titleIcon={<Layers className="size-5 text-primary" />}
        title={isUpdate ? "Update ISIN asset" : "Create new ISIN asset"}
        description="ISIN, asset class code, and portfolio inclusion."
        meta={
          isUpdate ? (
            <Button size="sm" className="gap-1.5" asChild>
              <Link href={CREATE_HREF}>
                <Plus className="size-4" />
                Create new
              </Link>
            </Button>
          ) : null
        }
      />

      <FormPanel title="Asset details">
        <div className="grid gap-6 md:grid-cols-3">
          <FormField label="ISIN" htmlFor="isin" required error={errors.isin}>
            <Input
              id="isin"
              className="font-mono"
              disabled={isUpdate}
              {...register("isin")}
            />
          </FormField>
          <FormField
            label="Asset class code"
            htmlFor="assetClassCode"
            required
            error={errors.assetClassCode}
          >
            <Input id="assetClassCode" {...register("assetClassCode")} />
          </FormField>
          <FormField
            label="In portfolio"
            htmlFor="inPortfolio"
            required
            error={errors.inPortfolio}
          >
            <Controller
              name="inPortfolio"
              control={control}
              render={({ field }) => (
                <SettingsSelect
                  value={field.value}
                  onValueChange={field.onChange}
                  options={YES_NO_OPTIONS}
                />
              )}
            />
          </FormField>
        </div>
      </FormPanel>

      <FormSaveBar
        cancelHref={LIST_HREF}
        isSaving={isSaving}
        onReset={() => form.reset(initialRow ? rowToValues(initialRow) : defaults)}
      />
    </form>
  );
}
