"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 { Braces, 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 { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { SettingsSelect } from "@/components/settings/ui/settings-select";
import type { SettingsSelectOption } from "@/components/settings/types";
import { requestDashboardApi } from "@/lib/dashboard-api-client";

import { CREATE_HREF, F_TYPE_OPTIONS, LIST_HREF } from "../constants";
import type { AssetFieldDefinitionRow } from "../schema";
import {
  assetFieldDefinitionFormSchema,
  type AssetFieldDefinitionFormValues,
} from "./schema";

type Props = {
  mode: "create" | "update";
  initialRow?: AssetFieldDefinitionRow;
  fTypeOptions?: SettingsSelectOption[];
};

function rowToFormValues(
  row: AssetFieldDefinitionRow,
): AssetFieldDefinitionFormValues {
  return {
    apiField: row.apiField,
    oxyField: row.oxyField,
    fType: row.fType || "please-select",
  };
}

const defaultValues: AssetFieldDefinitionFormValues = {
  apiField: "",
  oxyField: "",
  fType: "please-select",
};

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

  const defaultFormValues = useMemo(
    () => (initialRow ? rowToFormValues(initialRow) : defaultValues),
    [initialRow],
  );

  const form = useForm<AssetFieldDefinitionFormValues>({
    resolver: zodResolver(assetFieldDefinitionFormSchema),
    defaultValues: defaultFormValues,
  });

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

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

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

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

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

      toast.success(
        data.message ??
          `Asset field definition ${isUpdate ? "updated" : "created"}.`,
      );
      router.push(LIST_HREF);
      router.refresh();
    } catch (error) {
      toast.error(
        error instanceof Error
          ? error.message
          : `Asset field definition 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: "Asset Field Definition", href: LIST_HREF },
          { label: isUpdate ? "Update" : "Create new" },
        ]}
        titleIcon={<Braces className="size-5 text-primary" />}
        title={
          isUpdate
            ? "Update asset field definition"
            : "Create new asset field definition"
        }
        description="Map bank API fields to internal Oxy fields by file type."
        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="Field mapping">
        <div className="grid max-w-xl gap-6">
          <FormField
            label="API field"
            htmlFor="apiField"
            required
            error={errors.apiField}
          >
            <Input
              id="apiField"
              placeholder="e.g. pos:ISIN"
              className="font-mono text-sm"
              {...register("apiField")}
            />
          </FormField>

          <FormField
            label="Oxy field"
            htmlFor="oxyField"
            required
            error={errors.oxyField}
          >
            <Input
              id="oxyField"
              placeholder="e.g. ticker"
              className="font-mono text-sm"
              {...register("oxyField")}
            />
          </FormField>

          <FormField label="Field type" required error={errors.fType}>
            <Controller
              name="fType"
              control={control}
              render={({ field }) => (
                <SettingsSelect
                  value={field.value}
                  onValueChange={field.onChange}
                  options={fTypeOptions}
                  placeholder="Please select"
                />
              )}
            />
          </FormField>
        </div>
      </FormPanel>

      <FormSaveBar
        cancelHref={LIST_HREF}
        isSaving={isSaving}
        saveLabel="Save changes"
        onReset={() =>
          form.reset(initialRow ? rowToFormValues(initialRow) : defaultValues)
        }
      />
    </form>
  );
}
