"use client"

import { useEffect, useState } from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { ArrowLeft } from "lucide-react"

import { bankAccountsApi, cashAccountTypesApi } from "@/lib/api/general-ledger"
import { errorMessage } from "@/lib/error-map"
import { validateBankAccountForm } from "@/lib/validations/general-ledger"
import { cn } from "@/lib/utils"
import { CashAccountType, CashBankAccountType } from "@/types/general-ledger"

import { Button, buttonVariants } from "@/components/ui/button"
import { Field, FieldError, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { toast } from "@/components/ui/toast"

const OTHER_CASH_TYPE = "__other__"

export default function NewBankAccountPage() {
  const router = useRouter()

  const [accountType, setAccountType] = useState<CashBankAccountType>(CashBankAccountType.Bank)

  const [cashAccountTypes, setCashAccountTypes] = useState<CashAccountType[] | null>(null)
  const [cashAccountTypesError, setCashAccountTypesError] = useState<string | null>(null)

  const [accountName, setAccountName] = useState("")
  const [bankName, setBankName] = useState("")
  const [cashAccountTypeChoice, setCashAccountTypeChoice] = useState("")
  const [customCashAccountTypeName, setCustomCashAccountTypeName] = useState("")
  const [accountNumber, setAccountNumber] = useState("")
  const [currencyCode, setCurrencyCode] = useState("LKR")
  const [errors, setErrors] = useState<Record<string, string>>({})
  const [submitting, setSubmitting] = useState(false)

  useEffect(() => {
    if (accountType !== CashBankAccountType.Cash || cashAccountTypes !== null) return
    cashAccountTypesApi
      .list()
      .then(setCashAccountTypes)
      .catch((err) => setCashAccountTypesError(errorMessage(err)))
    // Only fetched once, lazily, the first time "Cash" is selected.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [accountType])

  const cashAccountTypeName =
    cashAccountTypeChoice === OTHER_CASH_TYPE ? customCashAccountTypeName.trim() : cashAccountTypeChoice

  async function handleSubmit() {
    const nextErrors = validateBankAccountForm({ accountName })
    if (accountType === CashBankAccountType.Cash && !cashAccountTypeName) {
      nextErrors.cashAccountTypeName = "Select or enter a cash account type"
    }
    setErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0) return

    setSubmitting(true)
    try {
      const created =
        accountType === CashBankAccountType.Bank
          ? await bankAccountsApi.createBank({
              accountName,
              bankName: bankName || null,
              accountNumber: accountNumber || null,
              currencyCode: currencyCode || undefined,
            })
          : await bankAccountsApi.createCash({
              accountName,
              cashAccountTypeName,
              accountNumber: accountNumber || null,
              currencyCode: currencyCode || undefined,
            })
      toast.success(`${accountType} account created`, `${created.accountName} — GL account ${created.glAccount.accountCode}`)
      router.push("/dashboard/accounts/bank-accounts")
    } catch (err) {
      toast.error(`Could not create ${accountType.toLowerCase()} account`, errorMessage(err))
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-3">
        <Link href="/dashboard/accounts/bank-accounts" className={cn(buttonVariants({ variant: "ghost", size: "icon-lg" }))}>
          <ArrowLeft className="size-5" />
        </Link>
        <div>
          <h1 className="text-2xl font-bold text-foreground">New Cash / Bank Account</h1>
          <p className="text-base text-muted-foreground">
            Its ledger account is created automatically — no need to pick one.
          </p>
        </div>
      </div>

      <div className="rounded-2xl bg-white p-6 shadow-sm ring-1 ring-black/5">
        <div className="mb-6 flex max-w-sm gap-2">
          <Button
            type="button"
            variant={accountType === CashBankAccountType.Bank ? "default" : "outline"}
            className="flex-1"
            onClick={() => setAccountType(CashBankAccountType.Bank)}
          >
            Bank
          </Button>
          <Button
            type="button"
            variant={accountType === CashBankAccountType.Cash ? "default" : "outline"}
            className="flex-1"
            onClick={() => setAccountType(CashBankAccountType.Cash)}
          >
            Cash
          </Button>
        </div>

        <div className="grid grid-cols-1 gap-x-6 gap-y-5 sm:grid-cols-2 lg:grid-cols-3">
          <Field data-invalid={!!errors.accountName}>
            <FieldLabel htmlFor="ba-name">Account name</FieldLabel>
            <Input
              id="ba-name"
              value={accountName}
              onChange={(e) => setAccountName(e.target.value)}
              placeholder={accountType === CashBankAccountType.Bank ? "Main Account" : "Head Office Petty Cash"}
              aria-invalid={!!errors.accountName}
            />
            <FieldError errors={[errors.accountName ? { message: errors.accountName } : undefined]} />
          </Field>

          {accountType === CashBankAccountType.Bank ? (
            <>
              <Field>
                <FieldLabel htmlFor="ba-bank">Bank name (optional)</FieldLabel>
                <Input id="ba-bank" value={bankName} onChange={(e) => setBankName(e.target.value)} placeholder="Commercial Bank" />
              </Field>
              <Field>
                <FieldLabel htmlFor="ba-acct-no">Account number (optional)</FieldLabel>
                <Input id="ba-acct-no" value={accountNumber} onChange={(e) => setAccountNumber(e.target.value)} placeholder="8001234567" />
              </Field>
            </>
          ) : (
            <>
              <Field data-invalid={!!errors.cashAccountTypeName}>
                <FieldLabel htmlFor="ba-cash-type">Cash account type</FieldLabel>
                <Select<string> value={cashAccountTypeChoice} onValueChange={(v) => setCashAccountTypeChoice(v ?? "")}>
                  <SelectTrigger id="ba-cash-type" className="w-full text-base" aria-invalid={!!errors.cashAccountTypeName}>
                    <SelectValue placeholder={cashAccountTypes === null ? "Loading…" : "Select a type"} />
                  </SelectTrigger>
                  <SelectContent>
                    {(cashAccountTypes ?? []).map((t) => (
                      <SelectItem key={t.cashAccountTypeId} value={t.name} label={t.name} className="text-base">
                        {t.name}
                      </SelectItem>
                    ))}
                    <SelectItem value={OTHER_CASH_TYPE} label="Other, please specify" className="text-base">
                      Other, please specify…
                    </SelectItem>
                  </SelectContent>
                </Select>
                {cashAccountTypeChoice === OTHER_CASH_TYPE && (
                  <Input
                    value={customCashAccountTypeName}
                    onChange={(e) => setCustomCashAccountTypeName(e.target.value)}
                    placeholder="e.g. Site Cash"
                    className="mt-2"
                  />
                )}
                {cashAccountTypesError && (
                  <p className="text-sm text-destructive">{cashAccountTypesError}</p>
                )}
                <FieldError errors={[errors.cashAccountTypeName ? { message: errors.cashAccountTypeName } : undefined]} />
              </Field>
              <Field>
                <FieldLabel htmlFor="ba-acct-no">Account number (optional)</FieldLabel>
                <Input
                  id="ba-acct-no"
                  value={accountNumber}
                  onChange={(e) => setAccountNumber(e.target.value)}
                  placeholder="Auto-generated if left blank"
                />
              </Field>
            </>
          )}

          <Field>
            <FieldLabel htmlFor="ba-currency">Currency</FieldLabel>
            <Input id="ba-currency" value={currencyCode} onChange={(e) => setCurrencyCode(e.target.value)} maxLength={3} placeholder="LKR" />
          </Field>
        </div>

        <div className="mt-6 flex justify-end gap-3">
          <Link href="/dashboard/accounts/bank-accounts" className={cn(buttonVariants({ variant: "outline" }), "min-w-36")}>
            Cancel
          </Link>
          <Button className="min-w-36" onClick={handleSubmit} disabled={submitting}>
            {submitting ? "Creating…" : "Create"}
          </Button>
        </div>
      </div>
    </div>
  )
}
