"use client"

import { useMemo, useState, useEffect } from "react"
import { useRouter } from "next/navigation"

import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Dropdown } from "@/components/ui/dropdown"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

import type { PayrollInput } from "@/features/payroll/schema"
import type { PayrollItem } from "@/features/payroll/types"

type Option = { id: string; name: string }

type EmployeeOption = {
  id: string
  fullName: string
  email: string | null
  branchId?: string | null
  departmentId?: string | null
}

type BranchOption = { id: string; name: string }

type PayrollFormProps = {
  initialData?: PayrollInput & { id?: string }
  employees: EmployeeOption[]
  branches: BranchOption[]
  currencyCode: string
  decimalPlaces: number
}

const monthNames = [
  "January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December",
]

export default function PayrollForm({
  initialData,
  employees,
  branches,
  currencyCode,
  decimalPlaces,
}: PayrollFormProps) {
  const router    = useRouter()
  const isEditing = Boolean(initialData?.id)

  const currentMonth = new Date().getMonth() + 1
  const currentYear  = new Date().getFullYear()

  const [loading, setLoading] = useState(false)
  const [error,   setError]   = useState("")

  // ── Branch / Dept cascade ─────────────────────────────────────────────────
  const [branchFilter, setBranchFilter] = useState("")
  const [deptFilter,   setDeptFilter]   = useState("")
  const [departments,  setDepartments]  = useState<Option[]>([])
  const [depsLoading,  setDepsLoading]  = useState(false)

  useEffect(() => {
    if (!branchFilter) { setDepartments([]); setDeptFilter(""); return }
    setDepsLoading(true)
    setDeptFilter("")
    fetch(`/api/departments?branchId=${branchFilter}`)
      .then(r => r.json())
      .then(setDepartments)
      .catch(() => setDepartments([]))
      .finally(() => setDepsLoading(false))
  }, [branchFilter])

  // ── Filtered employees ────────────────────────────────────────────────────
  const filteredEmployees = useMemo(() => {
    return employees.filter(e => {
      if (branchFilter && e.branchId !== branchFilter) return false
      if (deptFilter   && e.departmentId !== deptFilter) return false
      return true
    })
  }, [employees, branchFilter, deptFilter])

  // ── Core fields ───────────────────────────────────────────────────────────
  const [employeeId,  setEmployeeId]  = useState(initialData?.employeeId || "")
  const [month,       setMonth]       = useState(initialData?.month || currentMonth)
  const [year,        setYear]        = useState(initialData?.year  || currentYear)
  const [workingDays, setWorkingDays] = useState(initialData?.workingDays || 30)
  const [daysWorked,  setDaysWorked]  = useState(initialData?.daysWorked  || 30)
  const [basicSalary, setBasicSalary] = useState(initialData?.basicSalary || 0)
  const [notes,       setNotes]       = useState(initialData?.notes || "")

  const [items, setItems] = useState<PayrollItem[]>(
    initialData?.items?.length
      ? initialData.items
      : [
          { type: "ADDITION",  description: "", amount: 0 },
          { type: "DEDUCTION", description: "", amount: 0 },
        ]
  )

  // Reset employee when filtered out
  useEffect(() => {
    if (employeeId && !filteredEmployees.find(e => e.id === employeeId)) {
      setEmployeeId("")
    }
  }, [filteredEmployees, employeeId])

  const formatCurrency = (amount: number) =>
    new Intl.NumberFormat("en-US", {
      style: "currency", currency: currencyCode,
      minimumFractionDigits: decimalPlaces,
      maximumFractionDigits: decimalPlaces,
    }).format(amount)

  const calculations = useMemo(() => {
    const totalAdditions  = items.filter(i => i.type === "ADDITION").reduce((s, i) => s + (Number(i.amount) || 0), 0)
    const totalDeductions = items.filter(i => i.type === "DEDUCTION").reduce((s, i) => s + (Number(i.amount) || 0), 0)
    const dailyRate       = Number(basicSalary) / workingDays
    const proratedBasic   = dailyRate * daysWorked
    const netPayable      = proratedBasic + totalAdditions - totalDeductions
    return { dailyRate, proratedBasic, totalAdditions, totalDeductions, netPayable }
  }, [basicSalary, workingDays, daysWorked, items])

  function addItem(type: "ADDITION" | "DEDUCTION") {
    setItems(prev => [...prev, { type, description: "", amount: 0 }])
  }
  function updateItem(idx: number, patch: Partial<PayrollItem>) {
    setItems(prev => prev.map((item, i) => i === idx ? { ...item, ...patch } : item))
  }
  function removeItem(idx: number) {
    setItems(prev => prev.filter((_, i) => i !== idx))
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    setLoading(true)
    setError("")
    try {
      if (!employeeId) throw new Error("Please select an employee")

      const body: PayrollInput = {
        employeeId, month, year, workingDays, daysWorked,
        basicSalary: Number(basicSalary),
        items: items.filter(i => i.description.trim()).map(i => ({
          type: i.type, description: i.description, amount: Number(i.amount) || 0,
        })),
        notes: notes || undefined,
        status: "DRAFT",
      }

      const id  = initialData?.id
      const url = id ? `/api/payroll/${id}` : "/api/payroll"
      const res = await fetch(url, {
        method: id ? "PUT" : "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      })

      if (!res.ok) {
        const data = await res.json().catch(() => null)
        const detail = data?.details
          ? Array.isArray(data.details)
            ? data.details.map((d: { path?: string[]; message?: string }) => `${d.path?.join(".")}: ${d.message}`).join(", ")
            : String(data.details)
          : ""
        throw new Error(data?.error + (detail ? ` - ${detail}` : "") || "Failed to save payroll")
      }

      router.push("/payroll")
      router.refresh()
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : "Failed to save payroll")
    } finally {
      setLoading(false)
    }
  }

  // ── Dropdown option lists ─────────────────────────────────────────────────

  const branchOptions = branches.map(b => ({ value: b.id, label: b.name }))

  const departmentOptions = departments.map(d => ({ value: d.id, label: d.name }))

  const employeeOptions = filteredEmployees.map(e => ({
    value: e.id,
    label: e.fullName,
    description: e.email ?? undefined,
  }))

  const monthOptions = monthNames.map((name, idx) => ({
    value: String(idx + 1),
    label: name,
  }))

  const itemTypeOptions = [
    { value: "ADDITION",  label: "Addition"  },
    { value: "DEDUCTION", label: "Deduction" },
  ]

  // ─────────────────────────────────────────────────────────────────────────

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      {error && (
        <div className="rounded-lg border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive">
          {error}
        </div>
      )}

      {/* ── Employee Selection ── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-sm font-medium">Payroll Period & Employee</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">

          {/* Branch → Dept → Employee cascade */}
          {!isEditing && (
            <>
              <div className="grid gap-4 md:grid-cols-3">
                {/* Branch */}
                <Dropdown
                  label="Company"
                  placeholder="All Companies"
                  searchPlaceholder="Search companies…"
                  options={branchOptions}
                  value={branchFilter}
                  onChange={setBranchFilter}
                  clearable
                />

                {/* Department */}
                <div className="space-y-1.5">
                  <Dropdown
                    label={depsLoading ? "Department  (loading…)" : "Department"}
                    placeholder="All departments"
                    searchPlaceholder="Search departments…"
                    options={departmentOptions}
                    value={deptFilter}
                    onChange={setDeptFilter}
                    disabled={!branchFilter || depsLoading}
                    clearable
                  />
                  {branchFilter && !depsLoading && departments.length === 0 && (
                    <p className="text-xs text-muted-foreground">No departments for this branch.</p>
                  )}
                </div>

                {/* Employee */}
                <Dropdown
                  label={`Employee${filteredEmployees.length ? ` (${filteredEmployees.length})` : ""} *`}
                  placeholder="Select employee…"
                  searchPlaceholder="Search by name or email…"
                  options={employeeOptions}
                  value={employeeId}
                  onChange={setEmployeeId}
                  emptyMessage="No employees match the filters."
                />
              </div>

              <div className="border-t border-border" />
            </>
          )}

          {/* Month / Year */}
          <div className="grid gap-4 md:grid-cols-3">
            {isEditing && (
              <div className="space-y-1.5">
                <Label>Employee</Label>
                <div className="flex h-9 items-center rounded-lg border border-border/40 bg-muted/30 px-3 text-sm text-muted-foreground">
                  {employees.find(e => e.id === employeeId)?.fullName ?? "—"}
                </div>
              </div>
            )}

            {/* Month */}
            <Dropdown
              label="Month *"
              placeholder="Select month…"
              searchPlaceholder="Search month…"
              options={monthOptions}
              value={String(month)}
              onChange={(v) => setMonth(parseInt(v))}
              disabled={isEditing}
            />

            {/* Year */}
            <div className="space-y-1.5">
              <Label>Year *</Label>
              <Input
                type="number"
                value={year}
                onChange={e => setYear(parseInt(e.target.value))}
                min="2000" max="2100"
                required
                disabled={isEditing}
              />
            </div>
          </div>
        </CardContent>
      </Card>

      {/* ── Salary & Attendance ── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-sm font-medium">Salary & Attendance</CardTitle>
        </CardHeader>
        <CardContent className="grid gap-4 md:grid-cols-4">
          <div className="space-y-1.5">
            <Label>Basic Salary *</Label>
            <Input
              type="number" step="0.001" min="0"
              value={basicSalary}
              onChange={e => setBasicSalary(parseFloat(e.target.value) || 0)}
              required
            />
            {basicSalary > 0 && (
              <p className="text-xs text-muted-foreground">{formatCurrency(basicSalary)}</p>
            )}
          </div>
          <div className="space-y-1.5">
            <Label>Working Days *</Label>
            <Input
              type="number" min="1" max="31"
              value={workingDays}
              onChange={e => setWorkingDays(parseInt(e.target.value) || 30)}
              required
            />
          </div>
          <div className="space-y-1.5">
            <Label>Days Worked *</Label>
            <Input
              type="number" min="0" max="31"
              value={daysWorked}
              onChange={e => setDaysWorked(parseInt(e.target.value) || 0)}
              required
            />
            <p className="text-xs text-muted-foreground">
              Daily: {formatCurrency(calculations.dailyRate)}
            </p>
          </div>
          <div className="space-y-1.5">
            <Label>Prorated Basic</Label>
            <div className="flex h-9 items-center font-medium text-sm">
              {formatCurrency(calculations.proratedBasic)}
            </div>
          </div>
        </CardContent>
      </Card>

      {/* ── Additions & Deductions ── */}
      <Card>
        <CardHeader className="flex-row items-center justify-between">
          <CardTitle className="text-sm font-medium">Additions & Deductions</CardTitle>
          <div className="flex gap-2">
            <Button type="button" variant="secondary" size="sm" onClick={() => addItem("ADDITION")}>
              + Addition
            </Button>
            <Button type="button" variant="secondary" size="sm" onClick={() => addItem("DEDUCTION")}>
              + Deduction
            </Button>
          </div>
        </CardHeader>
        <CardContent className="space-y-4">
          {items.map((item, idx) => (
            <div key={idx} className="grid gap-4 md:grid-cols-12 items-end">
              {/* Type dropdown */}
              <div className="md:col-span-2">
                <Dropdown
                  label="Type"
                  options={itemTypeOptions}
                  value={item.type}
                  onChange={(v) => updateItem(idx, { type: v as "ADDITION" | "DEDUCTION" })}
                />
              </div>
              <div className="space-y-1.5 md:col-span-7">
                <Label>Description</Label>
                <Input
                  value={item.description}
                  onChange={e => updateItem(idx, { description: e.target.value })}
                  placeholder={item.type === "ADDITION" ? "e.g., Bonus, Overtime" : "e.g., Health Insurance, Loan"}
                />
              </div>
              <div className="space-y-1.5 md:col-span-2">
                <Label>Amount</Label>
                <Input
                  type="number" step="0.001" min="0"
                  value={item.amount}
                  onChange={e => updateItem(idx, { amount: parseFloat(e.target.value) || 0 })}
                />
              </div>
              <div className="md:col-span-1 flex items-end pb-0">
                <Button
                  type="button" variant="ghost" size="sm" className="h-9 w-full"
                  onClick={() => removeItem(idx)}
                  disabled={items.length <= 1}
                >
                  Remove
                </Button>
              </div>
            </div>
          ))}
        </CardContent>
      </Card>

      {/* ── Summary ── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-sm font-medium">Summary</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid grid-cols-2 gap-4 text-sm">
            <div className="space-y-1">
              <div className="flex justify-between">
                <span className="text-muted-foreground">Basic Salary (prorated)</span>
                <span>{formatCurrency(calculations.proratedBasic)}</span>
              </div>
              <div className="flex justify-between text-emerald-600">
                <span className="text-muted-foreground">+ Total Additions</span>
                <span>+{formatCurrency(calculations.totalAdditions)}</span>
              </div>
              <div className="flex justify-between text-red-500">
                <span className="text-muted-foreground">- Total Deductions</span>
                <span>-{formatCurrency(calculations.totalDeductions)}</span>
              </div>
              <div className="flex justify-between border-t pt-1 font-bold">
                <span>Net Payable</span>
                <span className="text-emerald-600">{formatCurrency(calculations.netPayable)}</span>
              </div>
            </div>
          </div>
          <div className="space-y-1.5">
            <Label>Notes</Label>
            <textarea
              className="min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
              value={notes}
              onChange={e => setNotes(e.target.value)}
              placeholder="Any additional notes about this payroll…"
            />
          </div>
        </CardContent>
      </Card>

      <div className="flex gap-4">
        <Button type="submit" disabled={loading}>
          {loading ? "Saving…" : isEditing ? "Update Payroll" : "Create Payroll"}
        </Button>
        <Button type="button" variant="secondary" onClick={() => router.push("/payroll")}>
          Cancel
        </Button>
      </div>
    </form>
  )
}