"use client";

import { API, authFetch } from "@/lib/api";
import { useState, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import {
  HandCoins,
  Plus,
  Search,
  Pencil,
  Trash2,
  X,
  Loader2,
  Download,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { downloadLoanReportPDF, downloadEmployeeLoanPDF } from "@/lib/pdf";

interface Employee {
  id: string;
  firstName: string;
  lastName: string;
  employeeId: string;
  department: string;
}

interface LoanRecord {
  id: string;
  employeeId: string;
  description: string;
  totalAmount: number;
  remainingBalance: number;
  status: string;
  issuedDate: string;
  employee: {
    firstName: string;
    lastName: string;
    employeeId: string;
    department: string;
  };
  deductions: { id: string; amount: number; month: number; year: number }[];
}

export default function LoansPage() {
  const [loans, setLoans] = useState<LoanRecord[]>([]);
  const [employees, setEmployees] = useState<Employee[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [searchQuery, setSearchQuery] = useState("");
  const [filterStatus, setFilterStatus] = useState<string>("all");
  const [downloading, setDownloading] = useState(false);

  const [slideOpen, setSlideOpen] = useState(false);
  const [editingLoan, setEditingLoan] = useState<LoanRecord | null>(null);
  const [isSaving, setIsSaving] = useState(false);

  const [form, setForm] = useState({
    employeeId: "",
    description: "",
    totalAmount: "",
    issuedDate: new Date().toISOString().slice(0, 10),
  });

  const fetchLoans = async () => {
    try {
      setIsLoading(true);
      const res = await authFetch(`${API}/loans`);
      const data = await res.json();
      if (res.ok && Array.isArray(data)) setLoans(data);
      else setLoans([]);
    } catch {
      setLoans([]);
    } finally {
      setIsLoading(false);
    }
  };

  const fetchEmployees = async () => {
    try {
      const res = await authFetch(`${API}/employees?limit=1000`);
      const data = await res.json();
      if (res.ok) {
        const empList = Array.isArray(data) ? data : data.employees;
        if (Array.isArray(empList)) setEmployees(empList);
      }
    } catch {
      /* ignore */
    }
  };

  useEffect(() => {
    fetchLoans();
    fetchEmployees();
  }, []);

  const openAdd = () => {
    setEditingLoan(null);
    setForm({
      employeeId: "",
      description: "",
      totalAmount: "",
      issuedDate: new Date().toISOString().slice(0, 10),
    });
    setSlideOpen(true);
  };

  const openEdit = (loan: LoanRecord) => {
    setEditingLoan(loan);
    setForm({
      employeeId: loan.employeeId,
      description: loan.description,
      totalAmount: String(loan.totalAmount),
      issuedDate: loan.issuedDate
        ? new Date(loan.issuedDate).toISOString().slice(0, 10)
        : "",
    });
    setSlideOpen(true);
  };

  const handleSave = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsSaving(true);
    try {
      if (editingLoan) {
        const res = await authFetch(`${API}/loans/${editingLoan.id}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            description: form.description,
            totalAmount: Number(form.totalAmount),
          }),
        });
        if (!res.ok) {
          const err = await res.json();
          alert(err.message || "Failed to update");
          return;
        }
      } else {
        const res = await authFetch(`${API}/loans`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            employeeId: form.employeeId,
            description: form.description,
            totalAmount: Number(form.totalAmount),
            issuedDate: form.issuedDate,
          }),
        });
        if (!res.ok) {
          const err = await res.json();
          alert(err.message || "Failed to create");
          return;
        }
      }
      setSlideOpen(false);
      fetchLoans();
    } catch (e) {
      console.error(e);
    } finally {
      setIsSaving(false);
    }
  };

  const handleDelete = async (id: string) => {
    if (!confirm("Delete this loan? This cannot be undone.")) return;
    try {
      const res = await authFetch(`${API}/loans/${id}`, { method: "DELETE" });
      if (!res.ok) {
        const err = await res.json();
        alert(err.message || "Failed to delete");
        return;
      }
      fetchLoans();
    } catch (e) {
      console.error(e);
    }
  };

  const handleStatusChange = async (id: string, status: string) => {
    try {
      await authFetch(`${API}/loans/${id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ status }),
      });
      fetchLoans();
    } catch (e) {
      console.error(e);
    }
  };

  const filtered = loans.filter((l) => {
    const q = searchQuery.toLowerCase();
    const matchSearch =
      l.employee?.firstName?.toLowerCase().includes(q) ||
      l.employee?.lastName?.toLowerCase().includes(q) ||
      l.employee?.employeeId?.toLowerCase().includes(q) ||
      l.description?.toLowerCase().includes(q);
    const matchStatus = filterStatus === "all" || l.status === filterStatus;
    return matchSearch && matchStatus;
  });

  const statusBadge = (status: string) => {
    const map: Record<string, string> = {
      ACTIVE: "bg-green-50 text-green-700 ring-green-600/20",
      COMPLETED: "bg-gray-100 text-gray-600 ring-gray-400/30",
      CANCELLED: "bg-red-50 text-red-700 ring-red-600/20",
    };
    return map[status] || "bg-gray-50 text-gray-600 ring-gray-400/30";
  };

  const fmtCurrency = (n: number) =>
    `Rs. ${n.toLocaleString("en-PK", { minimumFractionDigits: 0 })}`;

  const handleDownloadMonthlyReport = () => {
    if (loans.length === 0) return;
    setDownloading(true);
    try {
      const now = new Date();
      const m = now.getMonth() + 1;
      const y = now.getFullYear();
      const monthly = loans.filter((l) => {
        const d = new Date(l.issuedDate);
        return d.getMonth() + 1 === m && d.getFullYear() === y;
      });
      const periodLabel = `${now.toLocaleString("en-PK", { month: "long" })} ${y}`;
      downloadLoanReportPDF(monthly.length > 0 ? monthly : loans, periodLabel);
    } finally {
      setDownloading(false);
    }
  };

  return (
    <div className="space-y-6 relative">
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
            Loans / Advance
          </h1>
          <p className="mt-1 text-sm text-gray-500">
            Manage employee loans and salary advances.
          </p>
        </div>
        <div className="flex items-center gap-3">
          <button
            onClick={handleDownloadMonthlyReport}
            disabled={loans.length === 0 || downloading}
            className="inline-flex items-center justify-center rounded-lg border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 disabled:opacity-60"
          >
            <Download className="mr-2 h-4 w-4" />
            {downloading ? "Preparing PDF..." : "Download Loan PDF"}
          </button>
          <button
            onClick={openAdd}
            className="inline-flex items-center justify-center rounded-lg border border-transparent bg-brand-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-brand-700 transition-colors"
          >
            <Plus className="mr-2 h-4 w-4" />
            Add Loan
          </button>
        </div>
      </div>

      <div className="rounded-2xl bg-white shadow-sm border border-[#E2E8F0]">
        <div className="p-6 border-b border-gray-200 bg-gray-50/50 flex flex-col lg:flex-row lg:items-center justify-between gap-4">
          <div className="relative max-w-md w-full">
            <div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
              <Search className="h-4 w-4 text-gray-400" />
            </div>
            <input
              type="text"
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="block w-full rounded-lg border-0 py-2.5 pl-10 pr-3 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-brand-600 sm:text-sm sm:leading-6"
              placeholder="Search by employee or description..."
            />
          </div>
          <div className="flex items-center gap-3">
            <label className="text-xs font-bold text-gray-400 uppercase">
              Status:
            </label>
            <select
              value={filterStatus}
              onChange={(e) => setFilterStatus(e.target.value)}
              className="rounded-lg border-0 py-2 pl-3 pr-8 text-gray-900 ring-1 ring-inset ring-gray-200 focus:ring-2 focus:ring-brand-600 sm:text-sm"
            >
              <option value="all">All</option>
              <option value="ACTIVE">Active</option>
              <option value="COMPLETED">Completed</option>
              <option value="CANCELLED">Cancelled</option>
            </select>
          </div>
        </div>

        {isLoading ? (
          <div className="p-12 text-center text-sm text-gray-500">
            Loading loans...
          </div>
        ) : filtered.length === 0 ? (
          <div className="flex flex-col items-center justify-center p-16 text-center">
            <div className="flex h-16 w-16 items-center justify-center rounded-full bg-brand-50 mb-4">
              <HandCoins className="h-8 w-8 text-brand-600" />
            </div>
            <h3 className="text-lg font-medium text-gray-900">
              No loans found
            </h3>
            <p className="mt-1 text-sm text-gray-500 max-w-sm">
              Add a new loan or advance for an employee to get started.
            </p>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="min-w-full divide-y divide-gray-300">
              <thead className="bg-gray-50">
                <tr>
                  <th className="py-3.5 pl-6 pr-3 text-left text-sm font-semibold text-gray-900">
                    Employee
                  </th>
                  <th className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Description
                  </th>
                  <th className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Total Amount
                  </th>
                  <th className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Remaining
                  </th>
                  <th className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Deducted
                  </th>
                  <th className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Status
                  </th>
                  <th className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Issued
                  </th>
                  <th className="py-3.5 px-6 text-center text-sm font-semibold text-gray-900">
                    Actions
                  </th>
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-200 bg-white">
                {filtered.map((loan) => (
                  <motion.tr
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    key={loan.id}
                    className="hover:bg-gray-50 transition-colors"
                  >
                    <td className="whitespace-nowrap py-4 pl-6 pr-3 text-sm">
                      <div className="flex items-center">
                        <div className="h-10 w-10 flex-shrink-0 rounded-full bg-brand-100 flex items-center justify-center text-brand-700 font-bold uppercase ring-2 ring-white">
                          {loan.employee?.firstName?.charAt(0)}
                          {loan.employee?.lastName?.charAt(0)}
                        </div>
                        <div className="ml-4">
                          <div className="font-medium text-gray-900">
                            {loan.employee?.firstName}{" "}
                            {loan.employee?.lastName}
                          </div>
                          <div className="mt-0.5 text-gray-500 text-xs font-mono">
                            #{loan.employee?.employeeId}
                          </div>
                        </div>
                      </div>
                    </td>
                    <td className="whitespace-nowrap px-3 py-4 text-sm text-gray-700">
                      {loan.description}
                    </td>
                    <td className="whitespace-nowrap px-3 py-4 text-sm font-medium text-gray-900">
                      {fmtCurrency(loan.totalAmount)}
                    </td>
                    <td className="whitespace-nowrap px-3 py-4 text-sm font-bold text-brand-600">
                      {fmtCurrency(loan.remainingBalance)}
                    </td>
                    <td className="whitespace-nowrap px-3 py-4 text-sm text-red-600 font-medium">
                      {fmtCurrency(
                        loan.totalAmount - loan.remainingBalance
                      )}
                    </td>
                    <td className="whitespace-nowrap px-3 py-4 text-sm">
                      <select
                        value={loan.status}
                        onChange={(e) =>
                          handleStatusChange(loan.id, e.target.value)
                        }
                        className={cn(
                          "h-8 rounded-full border-0 bg-white px-3 text-xs font-medium shadow-sm ring-1 ring-inset focus:outline-none focus:ring-2",
                          statusBadge(loan.status)
                        )}
                      >
                        <option value="ACTIVE">Active</option>
                        <option value="COMPLETED">Completed</option>
                        <option value="CANCELLED">Cancelled</option>
                      </select>
                    </td>
                    <td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
                      {new Date(loan.issuedDate).toLocaleDateString(
                        "en-PK",
                        { day: "2-digit", month: "short", year: "numeric" }
                      )}
                    </td>
                    <td className="whitespace-nowrap py-4 px-6 text-center text-sm font-medium">
                      <div className="flex items-center justify-center gap-2">
                        <button
                          onClick={() => downloadEmployeeLoanPDF(loan)}
                          className="text-gray-600 hover:text-gray-900 bg-gray-50 p-2 rounded-lg"
                          title="Download employee loan PDF"
                        >
                          <Download className="h-4 w-4" />
                        </button>
                        <button
                          onClick={() => openEdit(loan)}
                          className="text-brand-600 hover:text-brand-900 bg-brand-50 p-2 rounded-lg"
                          title="Edit loan"
                        >
                          <Pencil className="h-4 w-4" />
                        </button>
                        <button
                          onClick={() => handleDelete(loan.id)}
                          className="text-red-600 hover:text-red-900 bg-red-50 p-2 rounded-lg"
                          title="Delete loan"
                        >
                          <Trash2 className="h-4 w-4" />
                        </button>
                      </div>
                    </td>
                  </motion.tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {/* Slide-over for Add/Edit Loan */}
      <AnimatePresence>
        {slideOpen && (
          <>
            <motion.div
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              onClick={() => setSlideOpen(false)}
              className="fixed inset-0 bg-gray-900/40 backdrop-blur-sm z-40"
            />
            <motion.div
              initial={{ x: "100%" }}
              animate={{ x: 0 }}
              exit={{ x: "100%" }}
              transition={{ type: "spring", bounce: 0, duration: 0.4 }}
              className="fixed inset-y-0 right-0 z-50 w-full max-w-md bg-white text-gray-900 shadow-2xl flex flex-col border-l border-gray-200"
            >
              <div className="flex items-center justify-between px-6 py-5 border-b border-gray-100 bg-white/50 backdrop-blur-md">
                <div className="flex items-center gap-3">
                  <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-brand-50 border border-brand-100">
                    <HandCoins className="h-5 w-5 text-brand-600" />
                  </div>
                  <div>
                    <h2 className="text-lg font-semibold text-gray-900">
                      {editingLoan ? "Edit Loan" : "Add Loan"}
                    </h2>
                    <p className="text-xs text-gray-500 font-medium mt-0.5">
                      {editingLoan
                        ? "Update loan details"
                        : "Create a new loan or advance"}
                    </p>
                  </div>
                </div>
                <button
                  onClick={() => setSlideOpen(false)}
                  className="rounded-full p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-600 transition-colors"
                >
                  <X className="h-5 w-5" />
                </button>
              </div>

              <div className="flex-1 overflow-y-auto px-6 py-6 bg-gray-50/30">
                <form
                  id="loan-form"
                  onSubmit={handleSave}
                  className="space-y-5"
                >
                  <div className="space-y-4 rounded-xl bg-white p-5 shadow-sm ring-1 ring-gray-900/5">
                    {!editingLoan && (
                      <div>
                        <label className="block text-xs font-semibold uppercase tracking-wider text-gray-500 mb-1.5">
                          Employee
                        </label>
                        <select
                          required
                          value={form.employeeId}
                          onChange={(e) =>
                            setForm({ ...form, employeeId: e.target.value })
                          }
                          className="block w-full rounded-lg border-0 py-2.5 pl-3 pr-8 text-gray-900 bg-gray-50 ring-1 ring-inset ring-gray-200 focus:bg-white focus:ring-2 focus:ring-brand-600 sm:text-sm transition-colors shadow-sm"
                        >
                          <option value="">Select employee...</option>
                          {employees.map((emp) => (
                            <option key={emp.id} value={emp.id}>
                              {emp.firstName} {emp.lastName} (#{emp.employeeId}
                              )
                            </option>
                          ))}
                        </select>
                      </div>
                    )}

                    <div>
                      <label className="block text-xs font-semibold uppercase tracking-wider text-gray-500 mb-1.5">
                        Description
                      </label>
                      <input
                        required
                        type="text"
                        value={form.description}
                        onChange={(e) =>
                          setForm({ ...form, description: e.target.value })
                        }
                        placeholder="e.g. Salary Advance, Personal Loan"
                        className="block w-full rounded-lg border-0 py-2.5 px-3 text-gray-900 bg-gray-50 ring-1 ring-inset ring-gray-200 focus:bg-white focus:ring-2 focus:ring-brand-600 sm:text-sm transition-colors shadow-sm"
                      />
                    </div>

                    <div>
                      <label className="block text-xs font-semibold uppercase tracking-wider text-gray-500 mb-1.5">
                        Total Amount (Rs.)
                      </label>
                      <input
                        required
                        type="number"
                        min="1"
                        step="1"
                        value={form.totalAmount}
                        onChange={(e) =>
                          setForm({ ...form, totalAmount: e.target.value })
                        }
                        placeholder="e.g. 50000"
                        className="block w-full rounded-lg border-0 py-2.5 px-3 text-gray-900 bg-gray-50 ring-1 ring-inset ring-gray-200 focus:bg-white focus:ring-2 focus:ring-brand-600 sm:text-sm transition-colors shadow-sm"
                      />
                    </div>

                    {!editingLoan && (
                      <div>
                        <label className="block text-xs font-semibold uppercase tracking-wider text-gray-500 mb-1.5">
                          Issued Date
                        </label>
                        <input
                          required
                          type="date"
                          value={form.issuedDate}
                          onChange={(e) =>
                            setForm({ ...form, issuedDate: e.target.value })
                          }
                          className="block w-full rounded-lg border-0 py-2.5 px-3 text-gray-900 bg-gray-50 ring-1 ring-inset ring-gray-200 focus:bg-white focus:ring-2 focus:ring-brand-600 sm:text-sm transition-colors shadow-sm"
                        />
                      </div>
                    )}
                  </div>
                </form>
              </div>

              <div className="border-t border-gray-100 px-6 py-4 bg-white flex items-center justify-between">
                <button
                  type="button"
                  onClick={() => setSlideOpen(false)}
                  className="rounded-lg bg-white px-4 py-2 text-sm font-semibold text-gray-700 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 transition-colors"
                >
                  Cancel
                </button>
                <button
                  type="submit"
                  form="loan-form"
                  disabled={isSaving}
                  className="inline-flex items-center rounded-lg bg-brand-600 px-6 py-2 text-sm font-semibold text-white shadow-sm hover:bg-brand-500 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  {isSaving ? (
                    <>
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      Saving...
                    </>
                  ) : editingLoan ? (
                    "Update Loan"
                  ) : (
                    "Create Loan"
                  )}
                </button>
              </div>
            </motion.div>
          </>
        )}
      </AnimatePresence>
    </div>
  );
}
