"use client"

import { toastApiError } from "@/lib/toast-api-error";
import { useRouter } from "next/navigation"
import { zodResolver } from "@hookform/resolvers/zod"
import { FileCode2 } from "lucide-react"
import { useEffect } from "react"
import { useForm } from "react-hook-form"
import { toast } from "sonner"

import {
  FormPageHeader,
  FormPanel,
  FormSaveBar,
} from "@/app/dashboard/_components/form"
import {
  createBankApi,
  updateBankApi,
} from "@/components/xml-apis/bank-api/api/bank-api.api"
import {
  bankApiCommonFields,
  bankApiConnectionFields,
  bankApiPositionFields,
} from "@/components/xml-apis/bank-api/data/bank-api-field-sections"
import {
  bankApiCreateDefaults,
  bankApiCreateSchema,
  bankApiEditSchema,
  type BankApiCreateFormInput,
  type BankApiCreateFormValues,
  type BankApiUpdateFormValues,
} from "@/components/xml-apis/bank-api/create/schema"
import { DeliveryServerRhfFields } from "@/components/settings/delivery-servers/create/components/delivery-server-rhf-fields"

const listHref = "/dashboard/xml-apis/bank-api"

const gridClass =
  "grid w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4 sm:gap-x-5 sm:gap-y-4"

type BankApiFormProps =
  | {
      mode: "create"
      initial?: undefined
    }
  | {
      mode: "update"
      initial: BankApiUpdateFormValues
    }

export function BankApiForm({ mode, initial }: BankApiFormProps) {
  const router = useRouter()
  const isUpdate = mode === "update"

  const form = useForm<BankApiCreateFormInput, unknown, BankApiCreateFormValues>({
    resolver: zodResolver(isUpdate ? bankApiEditSchema : bankApiCreateSchema),
    defaultValues: isUpdate ? toCreateFormValues(initial) : bankApiCreateDefaults,
    mode: "onBlur",
  })

  const {
    control,
    handleSubmit,
    reset,
    formState: { errors, isSubmitting },
  } = form

  useEffect(() => {
    if (isUpdate && initial) {
      reset(toCreateFormValues(initial))
    }
  }, [initial, isUpdate, reset])

  const onSubmit = handleSubmit(async (values) => {
    try {
      if (isUpdate) {
        await updateBankApi({
          bankId: initial.bankId,
          ...values,
        })
        toast.success("Bank API updated")
      } else {
        await createBankApi(values)
        toast.success("Bank API created")
      }
      router.push(listHref)
      router.refresh()
    } catch (error) {
      toastApiError(error, "Failed to save")
    }
  })

  return (
    <form onSubmit={(e) => void onSubmit(e)} className="pb-4">
      <FormPageHeader
        backHref={listHref}
        breadcrumb={[
          { label: "XML API" },
          { label: "Bank APIs", href: listHref },
          { label: isUpdate ? "Edit" : "Create new" },
        ]}
        titleIcon={<FileCode2 className="size-5 text-primary" />}
        title={isUpdate ? "Edit bank API" : "Create new bank API"}
        description={
          isUpdate
            ? "Update bank API connection settings and XML field mappings."
            : "Add a bank API connection with position and common field mappings."
        }
      />

      <div className="space-y-6">
        <FormPanel title="Connection" description="Bank API connection and credentials.">
          <DeliveryServerRhfFields
            fields={bankApiConnectionFields}
            control={control}
            errors={errors}
            gridClassName={gridClass}
          />
        </FormPanel>

        <FormPanel title="Settings position" description="Position XML field mappings.">
          <DeliveryServerRhfFields
            fields={bankApiPositionFields}
            control={control}
            errors={errors}
            gridClassName={gridClass}
          />
        </FormPanel>

        <FormPanel title="Settings common" description="Common XML field mappings.">
          <DeliveryServerRhfFields
            fields={bankApiCommonFields}
            control={control}
            errors={errors}
            gridClassName={gridClass}
          />
        </FormPanel>
      </div>

      <FormSaveBar
        cancelHref={listHref}
        isSaving={isSubmitting}
        saveLabel="Save changes"
        onReset={() =>
          reset(isUpdate && initial ? toCreateFormValues(initial) : bankApiCreateDefaults)
        }
      />
    </form>
  )
}

function toCreateFormValues(values: BankApiUpdateFormValues): BankApiCreateFormInput {
  const { bankId: _bankId, ...formValues } = values
  return formValues
}
