import { useEffect, useMemo, useState } from "react";
import { getDepartments } from "../api/departmentApi";
import { getEmployees } from "../api/employeeApi";
import { getMonthlyPayrollReport } from "../api/reportApi";
import { getSalaries } from "../api/salaryApi";

const currencyFormatter = new Intl.NumberFormat(undefined, {
  maximumFractionDigits: 0,
});

const formatNumber = (value) => {
  const number = Number(value);
  if (Number.isNaN(number)) return "-";
  return currencyFormatter.format(number);
};

function MetricCard({ label, value, helper, tone = "blue" }) {
  const tones = {
    blue: "border-blue-100 bg-blue-50 text-blue-900",
    green: "border-emerald-100 bg-emerald-50 text-emerald-900",
    amber: "border-amber-100 bg-amber-50 text-amber-900",
    slate: "border-slate-200 bg-slate-50 text-slate-900",
  };

  return (
    <div className={`rounded-xl border p-4 ${tones[tone] || tones.blue}`}>
      <div className="text-xs font-semibold uppercase text-slate-500">{label}</div>
      <div className="mt-2 text-3xl font-bold">{value}</div>
      {helper && <div className="mt-2 text-sm text-slate-600">{helper}</div>}
    </div>
  );
}

function DepartmentBar({ name, count, max }) {
  const width = max > 0 ? Math.max(8, Math.round((count / max) * 100)) : 0;

  return (
    <div>
      <div className="mb-1 flex items-center justify-between gap-3 text-sm">
        <span className="font-medium text-slate-800">{name}</span>
        <span className="text-slate-500">{count}</span>
      </div>
      <div className="h-2 rounded-full bg-slate-100">
        <div className="h-2 rounded-full bg-blue-600" style={{ width: `${width}%` }} />
      </div>
    </div>
  );
}

function DashboardPage() {
  const [employees, setEmployees] = useState([]);
  const [departments, setDepartments] = useState([]);
  const [salaries, setSalaries] = useState([]);
  const [rows, setRows] = useState([]);
  const [month, setMonth] = useState(() => new Date().toISOString().slice(0, 7));
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    let isMounted = true;

    const loadDashboard = async () => {
      setLoading(true);
      setMessage("");
      try {
        const [employeeRes, departmentRes, salaryRes, reportRes] = await Promise.all([
          getEmployees(),
          getDepartments(),
          getSalaries(),
          getMonthlyPayrollReport(month),
        ]);

        if (!isMounted) return;
        setEmployees(employeeRes.data);
        setDepartments(departmentRes.data);
        setSalaries(salaryRes.data);
        setRows(reportRes.data);
      } catch (error) {
        if (isMounted) {
          setMessage(error.response?.data?.message || "Failed to load dashboard data");
        }
      } finally {
        if (isMounted) setLoading(false);
      }
    };

    loadDashboard();
    return () => {
      isMounted = false;
    };
  }, [month]);

  const salaryTotals = useMemo(() => {
    const monthlySalaries = salaries.filter((salary) => salary.month === month);
    const totalGross = monthlySalaries.reduce((sum, salary) => sum + Number(salary.grossSalary || 0), 0);
    const totalDeductions = monthlySalaries.reduce((sum, salary) => sum + Number(salary.totalDeduction || 0), 0);
    const totalNet = monthlySalaries.reduce((sum, salary) => sum + Number(salary.netSalary || 0), 0);
    const allTimeNet = salaries.reduce((sum, salary) => sum + Number(salary.netSalary || 0), 0);

    return {
      allTimeNet,
      averageNet: monthlySalaries.length ? Math.round(totalNet / monthlySalaries.length) : 0,
      coverage: employees.length ? Math.round((monthlySalaries.length / employees.length) * 100) : 0,
      monthlyCount: monthlySalaries.length,
      totalDeductions,
      totalGross,
      totalNet,
    };
  }, [employees.length, month, salaries]);

  const recentEmployees = useMemo(() => {
    return [...employees]
      .sort((a, b) => new Date(b.createdAt || 0).getTime() - new Date(a.createdAt || 0).getTime())
      .slice(0, 5);
  }, [employees]);

  const employeesByDepartment = useMemo(() => {
    const counts = employees.reduce((acc, employee) => {
      const name = employee.department?.departmentName || "Unassigned";
      acc[name] = (acc[name] || 0) + 1;
      return acc;
    }, {});

    return Object.entries(counts)
      .map(([name, count]) => ({ name, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 5);
  }, [employees]);

  const maxDepartmentCount = Math.max(0, ...employeesByDepartment.map((item) => item.count));

  return (
    <div className="space-y-5">
      <section className="ui-card overflow-hidden">
        <div className="border-b border-slate-200 bg-slate-950 p-5 text-white">
          <div className="flex flex-wrap items-end justify-between gap-4">
            <div>
              <p className="text-sm font-medium text-blue-200">Payroll workspace</p>
              <h1 className="mt-1 text-3xl font-bold">Dashboard</h1>
              <p className="mt-2 max-w-2xl text-sm text-slate-300">
                Live totals from employees, departments, salaries, and monthly payroll reports.
              </p>
            </div>
            <div className="w-full sm:w-56">
              <label className="mb-1 block text-xs font-semibold uppercase text-slate-300">
                Payroll month
              </label>
              <input
                type="month"
                className="ui-input border-white/20 bg-white/10 text-white"
                value={month}
                onChange={(event) => setMonth(event.target.value)}
              />
            </div>
          </div>
        </div>
        <div className="grid gap-3 p-4 sm:grid-cols-2 lg:grid-cols-4">
          <MetricCard label="Employees" value={employees.length} helper="From employee page" />
          <MetricCard label="Departments" value={departments.length} helper="Active department records" tone="green" />
          <MetricCard label="Salary Records" value={salaries.length} helper={`${salaryTotals.monthlyCount} in ${month}`} tone="amber" />
          <MetricCard label="Payroll Coverage" value={`${salaryTotals.coverage}%`} helper="Employees paid this month" tone="slate" />
        </div>
      </section>

      {message && (
        <div className="rounded-xl bg-red-50 p-3 text-sm font-medium text-red-700 ring-1 ring-red-200">
          {message}
        </div>
      )}

      <div className="grid gap-4 lg:grid-cols-3">
        <section className="ui-card p-5 lg:col-span-2">
          <div className="flex flex-wrap items-start justify-between gap-3">
            <div>
              <h2 className="text-lg font-semibold text-slate-950">Monthly Payroll</h2>
              <p className="mt-1 text-sm text-slate-600">
                Gross pay, deductions, and net payroll for {month}.
              </p>
            </div>
            {loading && <span className="rounded-full bg-blue-50 px-3 py-1 text-xs font-semibold text-blue-700">Loading</span>}
          </div>

          <div className="mt-4 grid gap-3 sm:grid-cols-3">
            <MetricCard label="Gross Salary" value={formatNumber(salaryTotals.totalGross)} />
            <MetricCard label="Deductions" value={formatNumber(salaryTotals.totalDeductions)} tone="amber" />
            <MetricCard label="Net Salary" value={formatNumber(salaryTotals.totalNet)} helper={`Avg ${formatNumber(salaryTotals.averageNet)}`} tone="green" />
          </div>

          <div className="mt-4 ui-table-wrap">
            <table className="ui-table">
              <thead>
                <tr>
                  <th>Employee</th>
                  <th>Department</th>
                  <th>Position</th>
                  <th style={{ textAlign: "right" }}>Net Salary</th>
                </tr>
              </thead>
              <tbody>
                {rows.slice(0, 7).map((item) => (
                  <tr key={item.id}>
                    <td className="font-medium">
                      {item.firstName} {item.lastName}
                    </td>
                    <td>{item.department || "Unassigned"}</td>
                    <td>{item.position || "-"}</td>
                    <td style={{ textAlign: "right" }} className="font-semibold text-emerald-700">
                      {formatNumber(item.netSalary)}
                    </td>
                  </tr>
                ))}
                {!rows.length && (
                  <tr>
                    <td colSpan={4} className="py-5 text-center text-sm text-slate-600">
                      No payroll records found for this month.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </section>

        <aside className="space-y-4">
          <section className="ui-card p-5">
            <h2 className="text-lg font-semibold text-slate-950">Department Load</h2>
            <p className="mt-1 text-sm text-slate-600">Top departments by employee count.</p>
            <div className="mt-4 space-y-4">
              {employeesByDepartment.map((item) => (
                <DepartmentBar key={item.name} name={item.name} count={item.count} max={maxDepartmentCount} />
              ))}
              {!employeesByDepartment.length && <p className="text-sm text-slate-600">No employees assigned yet.</p>}
            </div>
          </section>

          <section className="ui-card p-5">
            <h2 className="text-lg font-semibold text-slate-950">Payroll Snapshot</h2>
            <div className="mt-4 grid gap-3">
              <div className="rounded-xl bg-slate-50 p-3 ring-1 ring-slate-200">
                <div className="text-xs font-semibold uppercase text-slate-500">All-time net payroll</div>
                <div className="mt-1 text-xl font-bold text-slate-950">{formatNumber(salaryTotals.allTimeNet)}</div>
              </div>
              <div className="rounded-xl bg-slate-50 p-3 ring-1 ring-slate-200">
                <div className="text-xs font-semibold uppercase text-slate-500">Monthly report rows</div>
                <div className="mt-1 text-xl font-bold text-slate-950">{rows.length}</div>
              </div>
            </div>
          </section>
        </aside>
      </div>

      <section className="ui-card p-5">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h2 className="text-lg font-semibold text-slate-950">Recent Employees</h2>
            <p className="mt-1 text-sm text-slate-600">Latest records from the employee page.</p>
          </div>
          <span className="rounded-full bg-slate-100 px-3 py-1 text-xs font-semibold text-slate-700">
            {employees.length} total
          </span>
        </div>
        <div className="mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-5">
          {recentEmployees.map((employee) => (
            <div key={employee._id} className="rounded-xl bg-white p-3 ring-1 ring-slate-200">
              <div className="text-sm font-semibold text-slate-950">
                {employee.firstName} {employee.lastName}
              </div>
              <div className="mt-1 text-xs text-slate-500">{employee.employeeNumber}</div>
              <div className="mt-3 text-sm text-slate-700">{employee.position}</div>
              <div className="mt-1 text-xs text-slate-500">{employee.department?.departmentName || "Unassigned"}</div>
            </div>
          ))}
          {!recentEmployees.length && <p className="text-sm text-slate-600">No employees yet.</p>}
        </div>
      </section>
    </div>
  );
}

export default DashboardPage;
