"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 { Package, 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 type { SettingsSelectOption } from "@/components/settings/types";
import { requestDashboardApi } from "@/lib/dashboard-api-client";

import { CREATE_HREF, LIST_HREF } from "../constants";
import type { AssetDefinitionRow } from "../schema";
import {
  assetDefinitionFormSchema,
  type AssetDefinitionFormValues,
} from "./schema";

type Props = {
  mode: "create" | "update";
  initialRow?: AssetDefinitionRow;
  moduleOptions: SettingsSelectOption[];
  listHref?: string;
  createHref?: string;
  pageTitle?: string;
  breadcrumbLabel?: string;
};

const defaults: AssetDefinitionFormValues = {
  apiName: "",
  oxyName: "",
  info: "",
};

function rowToValues(row: AssetDefinitionRow): AssetDefinitionFormValues {
  return {
    apiName: row.masterName,
    oxyName: row.oxyName,
    info: row.info,
  };
}

export function AssetDefinitionForm({
  mode,
  initialRow,
  moduleOptions,
  listHref = LIST_HREF,
  createHref = CREATE_HREF,
  pageTitle,
  breadcrumbLabel = "Asset Definition",
}: Props) {
  const router = useRouter();
  const isUpdate = mode === "update";
  const [isSaving, setIsSaving] = useState(false);

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

  const form = useForm<AssetDefinitionFormValues>({
    resolver: zodResolver(assetDefinitionFormSchema),
    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/asset-definition/update"
        : "/dashboard/master-table/asset-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 definition could not be ${isUpdate ? "updated" : "created"}.`,
        validate: (payload) => isApiSuccess(payload),
      });

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

  return (
    <form onSubmit={(e) => void onSubmit(e)} className="pb-4">
      <FormPageHeader
        backHref={listHref}
        breadcrumb={[
          { label: "Master Table", href: listHref },
          { label: breadcrumbLabel, href: listHref },
          { label: isUpdate ? "Update" : "Create new" },
        ]}
        titleIcon={<Package className="size-5 text-primary" />}
        title={
          pageTitle ??
          (isUpdate ? "Update asset definition" : "Create new asset definition")
        }
        description="Map bank API asset names to Oxy module codes."
        meta={
          isUpdate ? (
            <Button size="sm" className="gap-1.5" asChild>
              <Link href={createHref}>
                <Plus className="size-4" />
                Create new
              </Link>
            </Button>
          ) : null
        }
      />

      <FormPanel title="Definition details">
        <div className="grid gap-6 md:grid-cols-2">
          <FormField
            label="API name"
            htmlFor="apiName"
            required
            error={errors.apiName}
          >
            <Input id="apiName" {...register("apiName")} />
          </FormField>
          <FormField
            label="Oxy module"
            htmlFor="oxyName"
            required
            error={errors.oxyName}
          >
            <Controller
              name="oxyName"
              control={control}
              render={({ field }) => (
                <SettingsSelect
                  value={field.value}
                  onValueChange={field.onChange}
                  options={moduleOptions}
                  placeholder="Select module"
                />
              )}
            />
          </FormField>
        </div>
        <FormField
          label="Info"
          htmlFor="info"
          error={errors.info}
          className="mt-6"
        >
          <Input id="info" {...register("info")} />
        </FormField>
      </FormPanel>

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