"use client"

import { useState, useMemo, useEffect } from "react"
import { useRouter } from "next/navigation"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Badge } from "@/components/ui/badge"
import { Dropdown } from "@/components/ui/dropdown"

// ─── Types ────────────────────────────────────────────────────────────────────

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

type PublicHoliday = { date: string; endDate?: string | null }

type LeaveBalance = {
  leaveTypeId: string
  leaveTypeName: string
  totalDays: number
  usedDays: number
  remainingDays: number
}

type MyLeaveRequest = {
  id: string
  leaveTypeName: string
  startDate: string
  endDate: string
  duration: number
  status: "pending" | "approved" | "rejected"
  reason?: string | null
  rejectionReason?: string | null
  createdAt: string
  approvalTotal?: number
  approvalApproved?: number
}

type EmployeeLeavePageProps = {
  /** The logged-in employee's id */
  employeeId: string
  employeeName: string
  leaveTypes: LeaveType[]
  publicHolidays: PublicHoliday[]
  /** Pre-fetched requests for this employee */
  myRequests: MyLeaveRequest[]
  /** Pre-fetched balances for this employee */
  balances: LeaveBalance[]
}

// ─── Constants ────────────────────────────────────────────────────────────────

const STATUS_COLORS: Record<string, string> = {
  pending:  "bg-amber-50 text-amber-700 border-amber-200",
  approved: "bg-emerald-50 text-emerald-700 border-emerald-200",
  rejected: "bg-red-50 text-red-700 border-red-200",
}

const LEAVE_TYPE_BAR_COLORS: Record<string, string> = {
  annual:    "#E24B4A",
  sick:      "#1D9E75",
  "comp off":"#7F77DD",
  maternity: "#D4537E",
  paternity: "#378ADD",
  unpaid:    "#888780",
}

function getBarColor(name: string): string {
  const key = Object.keys(LEAVE_TYPE_BAR_COLORS).find((k) =>
    name.toLowerCase().includes(k)
  )
  return key ? LEAVE_TYPE_BAR_COLORS[key] : "#888780"
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

function parseDate(s: string | Date): Date {
  if (s instanceof Date) {
    const d = new Date(s); d.setHours(0, 0, 0, 0); return d
  }
  const datePart = s.includes("T") ? s.split("T")[0] : s
  const [y, m, d] = datePart.split("-").map(Number)
  return new Date(y, m - 1, d)
}

function fmtDate(s: string | Date): string {
  return parseDate(s).toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" })
}

function fmtShort(s: string | Date): string {
  return parseDate(s).toLocaleDateString("en-GB", { day: "2-digit", month: "short" })
}

function toDateInputValue(d?: Date | string | null): string {
  if (!d) return ""
  const date = d instanceof Date ? d : new Date(d)
  if (isNaN(date.getTime())) return ""
  return date.toISOString().slice(0, 10)
}

function getDatesInRange(start: string, end: string): Date[] {
  const dates: Date[] = []
  if (!start || !end) return dates
  const cur = new Date(start)
  const endD = new Date(end)
  while (cur <= endD) { dates.push(new Date(cur)); cur.setDate(cur.getDate() + 1) }
  return dates
}

function calculateDuration(
  start: string, end: string,
  excludeFridays: boolean, excludeHolidays: boolean,
  holidays: PublicHoliday[]
): { total: number; excluded: number; net: number } {
  const dates = getDatesInRange(start, end)
  if (!dates.length) return { total: 0, excluded: 0, net: 0 }
  let excluded = 0
  dates.forEach((d) => {
    const dow = d.getDay()
    if (excludeFridays && dow === 5) { excluded++; return }
    if (excludeHolidays) {
      const isHol = holidays.some((h) => {
        const hs = new Date(h.date); hs.setHours(0, 0, 0, 0)
        const he = h.endDate ? new Date(h.endDate) : new Date(h.date); he.setHours(23, 59, 59, 999)
        return d >= hs && d <= he
      })
      if (isHol) excluded++
    }
  })
  return { total: dates.length, excluded, net: dates.length - excluded }
}

// ─── Balance Card ─────────────────────────────────────────────────────────────

function BalanceCard({ b }: { b: LeaveBalance }) {
  const pct = b.totalDays > 0 ? Math.round((b.usedDays / b.totalDays) * 100) : 0
  const color = getBarColor(b.leaveTypeName)
  return (
    <div className="rounded-xl border border-slate-200 bg-white p-4 space-y-3 hover:shadow-md transition-shadow">
      <div className="flex items-center gap-2">
        <span className="inline-block w-3 h-3 rounded-sm shrink-0" style={{ background: color }} />
        <span className="text-sm font-semibold text-slate-900 truncate">{b.leaveTypeName}</span>
      </div>
      <div className="flex items-end justify-between">
        <div>
          <p className="text-3xl font-bold text-slate-900">{b.remainingDays}</p>
          <p className="text-xs text-slate-500 mt-0.5">days remaining</p>
        </div>
        <div className="text-right text-xs text-slate-500">
          <p>{b.usedDays} used</p>
          <p>{b.totalDays} total</p>
        </div>
      </div>
      {/* Progress bar */}
      <div className="h-1.5 w-full rounded-full bg-slate-100 overflow-hidden">
        <div
          className="h-full rounded-full transition-all"
          style={{ width: `${pct}%`, background: color }}
        />
      </div>
    </div>
  )
}

// ─── New Request Form ─────────────────────────────────────────────────────────

function NewRequestForm({
  employeeId,
  leaveTypes,
  publicHolidays,
  balances,
  onSuccess,
}: {
  employeeId: string
  leaveTypes: LeaveType[]
  publicHolidays: PublicHoliday[]
  balances: LeaveBalance[]
  onSuccess: () => void
}) {
  const router = useRouter()
  const [leaveTypeId, setLeaveTypeId]   = useState("")
  const [startDate,   setStartDate]     = useState("")
  const [endDate,     setEndDate]       = useState("")
  const [reason,  setReason]  = useState("")
  const [loading, setLoading] = useState(false)
  // Always exclude Fridays and public holidays — not configurable by employees
  const excludeFri = true
  const excludeHol = true
  const [error,       setError]         = useState("")

  const duration = useMemo(
    () => calculateDuration(startDate, endDate, excludeFri, excludeHol, publicHolidays),
    [startDate, endDate, excludeFri, excludeHol, publicHolidays]
  )

  const selectedBalance = balances.find((b) => b.leaveTypeId === leaveTypeId)
  const overLimit = selectedBalance && duration.net > selectedBalance.remainingDays
  const canSubmit = !!leaveTypeId && duration.net > 0 && !overLimit

  const leaveTypeOptions = leaveTypes.map((t) => ({ value: t.id, label: t.name }))

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!canSubmit) return
    setLoading(true); setError("")
    try {
      const res = await fetch("/api/leave-requests", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          employeeId, leaveTypeId,
          startDate: startDate ? new Date(startDate) : undefined,
          endDate:   endDate   ? new Date(endDate)   : undefined,
          duration:  duration.net,
          reason:    reason || undefined,
          excludeFridays: excludeFri, excludeHolidays: excludeHol,
        }),
      })
      if (!res.ok) {
        const data = await res.json().catch(() => null)
        throw new Error(data?.error || "Failed to submit leave request")
      }
      router.refresh()
      onSuccess()
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to submit request")
    } finally {
      setLoading(false)
    }
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-5">
      {error && (
        <div className="rounded-md border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600 font-medium">
          {error}
        </div>
      )}

      {/* Leave Type */}
      <div className="space-y-1.5">
        <Dropdown
          label="Leave Type *"
          placeholder="Select leave type…"
          searchPlaceholder="Search leave types…"
          options={leaveTypeOptions}
          value={leaveTypeId}
          onChange={setLeaveTypeId}
        />
        {selectedBalance && (
          <p className="text-xs text-slate-500 mt-1">
            Balance: <span className="font-semibold text-slate-900">{selectedBalance.remainingDays}</span> days remaining
          </p>
        )}
      </div>

      {/* Date Range */}
      <div className="grid gap-4 sm:grid-cols-2">
        <div className="space-y-1.5">
          <Label>Start Date *</Label>
          <Input
            type="date"
            value={startDate}
            onChange={(e) => { setStartDate(e.target.value); if (!endDate || e.target.value > endDate) setEndDate(e.target.value) }}
            required
          />
        </div>
        <div className="space-y-1.5">
          <Label>End Date *</Label>
          <Input
            type="date"
            value={endDate}
            min={startDate}
            onChange={(e) => setEndDate(e.target.value)}
            required
          />
        </div>
      </div>

      {/* Duration summary */}
      {startDate && endDate && (
        <div className={`rounded-lg border px-4 py-3 ${overLimit ? "border-red-200 bg-red-50" : "border-slate-200 bg-slate-50"}`}>
          <div className="flex items-center justify-between flex-wrap gap-2">
            <div className="flex items-center gap-6 text-sm">
              <span className="text-slate-500">Calendar days: <strong className="text-slate-900">{duration.total}</strong></span>
              {duration.excluded > 0 && (
                <span className="text-slate-500">Excluded: <strong className="text-amber-600">−{duration.excluded}</strong></span>
              )}
              <span className="text-slate-500">
                Leave days: <strong className={overLimit ? "text-red-600" : "text-emerald-700"}>{duration.net}</strong>
              </span>
            </div>
            {selectedBalance && duration.net > 0 && (
              <span className={`text-xs font-semibold ${overLimit ? "text-red-600" : "text-emerald-600"}`}>
                {overLimit
                  ? `⚠ Exceeds balance by ${duration.net - selectedBalance.remainingDays} day(s)`
                  : `✓ ${selectedBalance.remainingDays - duration.net} days left after`}
              </span>
            )}
          </div>
        </div>
      )}

      {/* Reason */}
      <div className="space-y-1.5">
        <Label>Reason <span className="text-muted-foreground text-xs">(optional)</span></Label>
        <Input
          value={reason}
          onChange={(e) => setReason(e.target.value)}
          placeholder="Brief reason for your leave…"
        />
      </div>

      <div className="flex justify-end gap-3 pt-1">
        <Button type="submit" disabled={loading || !canSubmit}>
          {loading ? "Submitting…" : "Submit Request"}
        </Button>
      </div>
    </form>
  )
}

// ─── My Requests Table ────────────────────────────────────────────────────────

function MyRequestsTable({ requests }: { requests: MyLeaveRequest[] }) {
  const [statusFilter, setStatusFilter] = useState("")

  const filtered = useMemo(() =>
    statusFilter ? requests.filter((r) => r.status === statusFilter) : requests
  , [requests, statusFilter])

  const STATUS_OPTIONS = [
    { value: "", label: "All statuses" },
    { value: "pending",  label: "Pending" },
    { value: "approved", label: "Approved" },
    { value: "rejected", label: "Rejected" },
  ]

  if (requests.length === 0) {
    return (
      <div className="py-16 text-center text-sm text-slate-500">
        <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="mx-auto mb-3 text-slate-300">
          <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/>
        </svg>
        <p className="font-medium">You haven't submitted any leave requests yet</p>
        <p className="text-xs mt-1 text-slate-400">Use the form above to submit your first request</p>
      </div>
    )
  }

  return (
    <div className="space-y-3">
      <div className="flex items-center gap-3 px-6 py-3 border-b border-slate-200 bg-slate-50/70">
        <span className="text-xs font-bold uppercase tracking-widest text-slate-500">Filter</span>
        <div className="w-36">
          <Dropdown
            placeholder="All statuses"
            options={STATUS_OPTIONS}
            value={statusFilter}
            onChange={setStatusFilter}
          />
        </div>
        <span className="ml-auto text-xs text-slate-500">
          {filtered.length} request{filtered.length !== 1 ? "s" : ""}
        </span>
      </div>

      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead className="border-b bg-gradient-to-r from-slate-50 to-white">
            <tr>
              {["Leave Type", "Dates", "Days", "Status", "Requested On", "Notes"].map((h) => (
                <th key={h} className="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider text-slate-700">
                  {h}
                </th>
              ))}
            </tr>
          </thead>
          <tbody className="divide-y divide-slate-100">
            {filtered.map((r) => (
              <tr key={r.id} className="hover:bg-blue-50/30 transition-colors">
                <td className="px-6 py-4">
                  <span className="flex items-center gap-2">
                    <span className="inline-block w-2.5 h-2.5 rounded shrink-0" style={{ background: getBarColor(r.leaveTypeName) }} />
                    <span className="font-medium text-slate-900">{r.leaveTypeName}</span>
                  </span>
                </td>
                <td className="px-6 py-4 text-xs text-slate-600 whitespace-nowrap">
                  {fmtShort(r.startDate)} → {fmtShort(r.endDate)}
                </td>
                <td className="px-6 py-4">
                  <span className="font-bold text-slate-900">{r.duration}</span>
                  <span className="text-slate-400"> d</span>
                </td>
                <td className="px-6 py-4">
                  <Badge variant="outline" className={`${STATUS_COLORS[r.status]} border rounded-full font-bold text-xs`}>
                    {r.status === "pending" ? "Pending approval" : r.status.charAt(0).toUpperCase() + r.status.slice(1)}
                  </Badge>
                  {r.status === "pending" && (r.approvalTotal ?? 0) > 0 && (
                    <p className="text-[10px] text-slate-400 mt-1">
                      {r.approvalApproved ?? 0}/{r.approvalTotal} approvers signed off
                    </p>
                  )}
                </td>
                <td className="px-6 py-4 text-xs text-slate-500 whitespace-nowrap">
                  {fmtDate(r.createdAt)}
                </td>
                <td className="px-6 py-4 text-xs text-slate-500 max-w-[200px]">
                  {r.status === "rejected" && r.rejectionReason ? (
                    <span className="text-red-600">Rejected: {r.rejectionReason}</span>
                  ) : r.reason ? (
                    <span className="truncate block">{r.reason}</span>
                  ) : (
                    <span className="text-slate-300">—</span>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  )
}

// ─── Main Page Component ──────────────────────────────────────────────────────

export default function EmployeeLeavePage({
  employeeId,
  employeeName,
  leaveTypes,
  publicHolidays,
  myRequests,
  balances,
}: EmployeeLeavePageProps) {
  const [tab, setTab] = useState<"request" | "history">("request")
  const [successMsg, setSuccessMsg] = useState(false)

  function handleSuccess() {
    setSuccessMsg(true)
    setTab("history")
    setTimeout(() => setSuccessMsg(false), 5000)
  }

  const pendingCount = myRequests.filter((r) => r.status === "pending").length

  return (
    <div className="space-y-6">
      {/* Success toast */}
      {successMsg && (
        <div className="rounded-lg border border-emerald-200 bg-emerald-50 px-5 py-3 text-sm font-medium text-emerald-700 flex items-center gap-2">
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" className="shrink-0">
            <polyline points="20 6 9 17 4 12"/>
          </svg>
          Your leave request was submitted successfully and is pending approval.
        </div>
      )}

      {/* Balance Summary */}
      {balances.length > 0 && (
        <div>
          <h3 className="text-xs font-bold uppercase tracking-widest text-slate-500 mb-3">Your Leave Balance</h3>
          <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
            {balances.map((b) => (
              <BalanceCard key={b.leaveTypeId} b={b} />
            ))}
          </div>
        </div>
      )}

      {/* Tab Bar */}
      <div className="inline-flex items-center rounded-lg border border-border bg-muted p-1 gap-1">
        <button
          onClick={() => setTab("request")}
          className={`inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-all duration-150 ${
            tab === "request" ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
          }`}
        >
          <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
          </svg>
          New Request
        </button>
        <button
          onClick={() => setTab("history")}
          className={`inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-all duration-150 ${
            tab === "history" ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
          }`}
        >
          <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>
          </svg>
          My Requests
          {pendingCount > 0 && (
            <span className="inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-amber-500 text-white text-[10px] font-bold px-1">
              {pendingCount}
            </span>
          )}
        </button>
      </div>

      {/* Tab Content */}
      {tab === "request" ? (
        <Card className="border-slate-200 shadow-sm">
          <CardHeader className="border-b border-slate-100 bg-gradient-to-r from-slate-50 to-white">
            <CardTitle className="text-base font-bold text-slate-900">Submit a Leave Request</CardTitle>
            <p className="text-sm text-slate-500 mt-1">
              Submitting as <span className="font-semibold text-slate-700">{employeeName}</span>
            </p>
          </CardHeader>
          <CardContent className="p-6">
            <NewRequestForm
              employeeId={employeeId}
              leaveTypes={leaveTypes}
              publicHolidays={publicHolidays}
              balances={balances}
              onSuccess={handleSuccess}
            />
          </CardContent>
        </Card>
      ) : (
        <Card className="border-slate-200 shadow-sm overflow-hidden">
          <CardHeader className="border-b border-slate-100 bg-gradient-to-r from-slate-50 to-white">
            <CardTitle className="text-base font-bold text-slate-900">My Leave History</CardTitle>
          </CardHeader>
          <CardContent className="p-0">
            <MyRequestsTable requests={myRequests} />
          </CardContent>
        </Card>
      )}
    </div>
  )
}