import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  PieChart,
  Pie,
  Cell,
  Legend,
} from 'recharts';
import {
  Building2,
  ClipboardList,
  ClipboardCheck,
  CalendarDays,
  Server,
  Briefcase,
  RefreshCw,
  ArrowRight,
  Layers,
} from 'lucide-react';
import { dataService } from '../services/dataService';
import {
  IProject,
  ITicket,
  IWorkOrder,
  IPMSchedule,
  IAsset,
  IContract,
} from '../types';
import { useTheme } from '../App';
import { getTicketProjectIdString, getTicketProjectName } from '../utils/ticketProject';

const CHART_COLORS = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#64748b'];

function dedupeById<T extends { _id?: unknown }>(items: T[]): T[] {
  const unique = new Map<string, T>();
  items.forEach((item) => {
    const id = item?._id != null ? String(item._id) : '';
    if (!id) return;
    if (!unique.has(id)) unique.set(id, item);
  });
  return Array.from(unique.values());
}

async function loadAcrossProjects<T extends { _id?: unknown }>(
  projList: IProject[],
  loader: (projectId: string) => Promise<T[]>
): Promise<T[]> {
  const projectIds = projList
    .map((p) => (p?._id != null ? String(p._id) : ''))
    .filter(Boolean);

  if (!projectIds.length) return [];
  const rows = await Promise.all(projectIds.map((projectId) => loader(projectId).catch(() => [] as T[])));
  return dedupeById(rows.flat());
}

async function loadAllTicketsAcrossProjects(projList: IProject[]): Promise<ITicket[]> {
  return loadAcrossProjects(projList, (projectId) => dataService.getTickets(projectId));
}

const Dashboard: React.FC = () => {
  const { isDarkMode } = useTheme();
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [projects, setProjects] = useState<IProject[]>([]);
  const [tickets, setTickets] = useState<ITicket[]>([]);
  const [workOrders, setWorkOrders] = useState<IWorkOrder[]>([]);
  const [pmSchedules, setPmSchedules] = useState<IPMSchedule[]>([]);
  const [assets, setAssets] = useState<IAsset[]>([]);
  const [contracts, setContracts] = useState<IContract[]>([]);
  const [lastUpdated, setLastUpdated] = useState<Date>(new Date());

  const load = useCallback(async (isRefresh = false) => {
    try {
      if (isRefresh) setRefreshing(true);
      else setLoading(true);
      setError(null);
      const projList = await dataService.getProjects();
      setProjects(projList);

      let tix: ITicket[] = [];
      let wos: IWorkOrder[] = [];
      let pms: IPMSchedule[] = [];
      let ast: IAsset[] = [];
      let ctr: IContract[] = [];

      tix = await loadAllTicketsAcrossProjects(projList);

      [wos, pms, ast, ctr] = await Promise.all([
        loadAcrossProjects(projList, (projectId) => dataService.getWorkOrders(projectId)),
        loadAcrossProjects(projList, (projectId) => dataService.getPMSchedules(projectId)),
        loadAcrossProjects(projList, (projectId) => dataService.getAssets(projectId)),
        loadAcrossProjects(projList, (projectId) => dataService.getContracts(projectId)),
      ]);

      setTickets(tix || []);
      setWorkOrders(wos || []);
      setPmSchedules(pms || []);
      setAssets(ast || []);
      setContracts(ctr || []);
      setLastUpdated(new Date());
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Không thể tải dữ liệu tổng quan');
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  const projectNameById = useMemo(() => {
    const m = new Map<string, string>();
    projects.forEach((p) => m.set(String(p._id), p.name));
    return m;
  }, [projects]);

  const stats = useMemo(() => {
    const activeContractStatuses = ['active', 'negotiating', 'suspended', 'completed', 'Expiring'];
    const openTickets = tickets.filter(
      (t) => !['Closed', 'Resolved'].includes(String(t.status))
    ).length;
    const woInProgress = workOrders.filter((w) =>
      ['InProgress', 'In Progress', 'Approved'].includes(String(w.status))
    ).length;
    const pmActive = pmSchedules.filter((s) => s.status === 'Active').length;
    const totalCapacityMWp = projects.reduce((s, p) => s + (p.capacityMWp || 0), 0);
    const activeContracts = contracts.filter((c) => activeContractStatuses.includes(String(c.status))).length;
    return {
      projectCount: projects.length,
      totalCapacityMWp,
      openTickets,
      woInProgress,
      pmActive,
      assetCount: assets.length,
      activeContracts,
      ticketTotal: tickets.length,
      woTotal: workOrders.length,
      pmTotal: pmSchedules.length,
    };
  }, [projects, tickets, workOrders, pmSchedules, assets, contracts]);

  const ticketsByStatus = useMemo(() => {
    const map = new Map<string, number>();
    tickets.forEach((t) => {
      const k = String(t.status || 'Unknown');
      map.set(k, (map.get(k) || 0) + 1);
    });
    return Array.from(map.entries())
      .map(([name, value]) => ({ name, value }))
      .sort((a, b) => b.value - a.value)
      .slice(0, 8);
  }, [tickets]);

  const topProjectsByTickets = useMemo(() => {
    const map = new Map<string, { count: number; label: string }>();
    tickets.forEach((t) => {
      const pid = getTicketProjectIdString(t);
      if (!pid) return;
      const label = getTicketProjectName(t, projectNameById);
      const prev = map.get(pid);
      const bestLabel = label !== '—' ? label : prev?.label && prev.label !== '—' ? prev.label : label;
      map.set(pid, { count: (prev?.count || 0) + 1, label: bestLabel });
    });
    return Array.from(map.entries())
      .map(([projectId, { count, label }]) => ({
        id: projectId,
        name: label !== '—' ? label : projectId.slice(0, 8),
        count,
      }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 6);
  }, [tickets, projectNameById]);

  const gridText = isDarkMode ? '#94a3b8' : '#64748b';
  const tooltipBg = isDarkMode ? '#1e293b' : '#fff';

  if (loading && !projects.length) {
    return (
      <div className="flex items-center justify-center h-64 text-slate-500 dark:text-slate-400">
        Đang tải tổng quan toàn hệ thống...
      </div>
    );
  }

  return (
    <div className="space-y-6 pb-10">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold text-slate-800 dark:text-white">Tổng quan</h1>
          <p className="text-sm text-slate-500 dark:text-slate-400 mt-1">
            Tổng hợp đa dự án: tài sản, hợp đồng, O&amp;M — không giới hạn theo một dự án đang chọn.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <span className="text-xs text-slate-500 dark:text-slate-400">
            Cập nhật: {lastUpdated.toLocaleString('vi-VN')}
          </span>
          <button
            type="button"
            onClick={() => load(true)}
            disabled={refreshing}
            className="p-2 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 hover:bg-slate-50 dark:hover:bg-slate-700 disabled:opacity-50"
            title="Làm mới"
          >
            <RefreshCw size={18} className={refreshing ? 'animate-spin text-slate-600' : 'text-slate-600'} />
          </button>
        </div>
      </div>

      {error && (
        <div className="rounded-lg border border-red-200 dark:border-red-900/50 bg-red-50 dark:bg-red-900/20 px-4 py-3 text-sm text-red-800 dark:text-red-200">
          {error}
        </div>
      )}

      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm">
          <div className="flex items-center justify-between">
            <p className="text-xs font-semibold text-slate-500 uppercase">Dự án</p>
            <Building2 className="text-blue-500" size={20} />
          </div>
          <p className="text-2xl font-bold text-slate-900 dark:text-white mt-2">{stats.projectCount}</p>
          <p className="text-xs text-slate-500 mt-1">{stats.totalCapacityMWp.toFixed(2)} MWp tổng</p>
        </div>
        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm">
          <div className="flex items-center justify-between">
            <p className="text-xs font-semibold text-slate-500 uppercase">Phiếu (Ticket)</p>
            <ClipboardList className="text-amber-500" size={20} />
          </div>
          <p className="text-2xl font-bold text-slate-900 dark:text-white mt-2">{stats.ticketTotal}</p>
          <p className="text-xs text-slate-500 mt-1">{stats.openTickets} chưa đóng</p>
        </div>
        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm">
          <div className="flex items-center justify-between">
            <p className="text-xs font-semibold text-slate-500 uppercase">Work order</p>
            <ClipboardCheck className="text-emerald-500" size={20} />
          </div>
          <p className="text-2xl font-bold text-slate-900 dark:text-white mt-2">{stats.woTotal}</p>
          <p className="text-xs text-slate-500 mt-1">{stats.woInProgress} đang thực hiện</p>
        </div>
        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm">
          <div className="flex items-center justify-between">
            <p className="text-xs font-semibold text-slate-500 uppercase">Lịch PM</p>
            <CalendarDays className="text-violet-500" size={20} />
          </div>
          <p className="text-2xl font-bold text-slate-900 dark:text-white mt-2">{stats.pmTotal}</p>
          <p className="text-xs text-slate-500 mt-1">{stats.pmActive} đang active</p>
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm flex items-center justify-between">
          <div>
            <p className="text-xs font-semibold text-slate-500 uppercase">Tài sản</p>
            <p className="text-xl font-bold text-slate-900 dark:text-white mt-1">{stats.assetCount}</p>
          </div>
          <Server className="text-slate-400" size={22} />
        </div>
        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm flex items-center justify-between">
          <div>
            <p className="text-xs font-semibold text-slate-500 uppercase">Hợp đồng hoạt động</p>
            <p className="text-xl font-bold text-slate-900 dark:text-white mt-1">{stats.activeContracts}</p>
          </div>
          <Briefcase className="text-slate-400" size={22} />
        </div>
        <Link
          to="/om-dashboard"
          className="bg-gradient-to-br from-blue-600 to-indigo-700 rounded-xl p-4 text-white shadow-md flex items-center justify-between hover:opacity-95 transition-opacity"
        >
          <div>
            <p className="text-xs font-semibold uppercase opacity-90">O&amp;M</p>
            <p className="text-sm font-bold mt-1">Mở O&amp;M Dashboard</p>
          </div>
          <ArrowRight size={22} />
        </Link>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm">
          <h2 className="text-sm font-bold text-slate-800 dark:text-white mb-4">Phiếu theo trạng thái</h2>
          <div className="h-72 min-h-[288px] w-full min-w-0">
            <ResponsiveContainer width="100%" height="100%" minWidth={0} debounce={100}>
              <BarChart data={ticketsByStatus} margin={{ top: 8, right: 8, left: 0, bottom: 40 }}>
                <CartesianGrid strokeDasharray="3 3" stroke={gridText} opacity={0.3} />
                <XAxis dataKey="name" tick={{ fontSize: 10, fill: gridText }} angle={-25} textAnchor="end" height={60} />
                <YAxis tick={{ fontSize: 11, fill: gridText }} allowDecimals={false} />
                <Tooltip contentStyle={{ background: tooltipBg, border: '1px solid #334155', borderRadius: 8 }} />
                <Bar dataKey="value" name="Số lượng" radius={[4, 4, 0, 0]}>
                  {ticketsByStatus.map((_, i) => (
                    <Cell key={i} fill={CHART_COLORS[i % CHART_COLORS.length]} />
                  ))}
                </Bar>
              </BarChart>
            </ResponsiveContainer>
          </div>
        </div>

        <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm">
          <h2 className="text-sm font-bold text-slate-800 dark:text-white mb-4">Phân bổ ticket (Top)</h2>
          <div className="h-72 min-h-[288px] w-full min-w-0">
            <ResponsiveContainer width="100%" height="100%" minWidth={0} debounce={100}>
              <PieChart>
                <Pie
                  data={ticketsByStatus.slice(0, 6)}
                  dataKey="value"
                  nameKey="name"
                  cx="50%"
                  cy="50%"
                  outerRadius={90}
                  label={({ name, percent }) => `${name} ${(percent * 100).toFixed(0)}%`}
                >
                  {ticketsByStatus.slice(0, 6).map((_, i) => (
                    <Cell key={i} fill={CHART_COLORS[i % CHART_COLORS.length]} />
                  ))}
                </Pie>
                <Tooltip contentStyle={{ background: tooltipBg, border: '1px solid #334155', borderRadius: 8 }} />
                <Legend wrapperStyle={{ fontSize: 11 }} />
              </PieChart>
            </ResponsiveContainer>
          </div>
        </div>
      </div>

      <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden shadow-sm">
        <div className="px-4 py-3 border-b border-slate-200 dark:border-slate-700 flex items-center justify-between">
          <h2 className="text-sm font-bold text-slate-800 dark:text-white flex items-center gap-2">
            <Layers size={18} className="text-blue-500" />
            Dự án có nhiều ticket nhất
          </h2>
          <Link to="/operations" className="text-xs font-medium text-blue-600 dark:text-blue-400 hover:underline">
            Chi tiết ticket →
          </Link>
        </div>
        <div className="overflow-x-auto">
          <table className="min-w-full text-sm">
            <thead className="bg-slate-50 dark:bg-slate-900/50 text-slate-500 dark:text-slate-400">
              <tr>
                <th className="text-left px-4 py-2 font-semibold">Dự án</th>
                <th className="text-right px-4 py-2 font-semibold">Số ticket</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-100 dark:divide-slate-700">
              {topProjectsByTickets.length === 0 ? (
                <tr>
                  <td colSpan={2} className="px-4 py-8 text-center text-slate-500">
                    Chưa có dữ liệu ticket
                  </td>
                </tr>
              ) : (
                topProjectsByTickets.map((row) => (
                  <tr key={row.id} className="hover:bg-slate-50 dark:hover:bg-slate-700/40">
                    <td className="px-4 py-2.5 text-slate-800 dark:text-slate-200">{row.name}</td>
                    <td className="px-4 py-2.5 text-right font-semibold text-slate-700 dark:text-slate-300">{row.count}</td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </div>

      <div className="flex flex-wrap gap-2">
        <Link
          to="/assets"
          className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-slate-100 dark:bg-slate-700 text-sm font-medium text-slate-800 dark:text-slate-200 hover:bg-slate-200 dark:hover:bg-slate-600"
        >
          Hồ sơ tài sản <ArrowRight size={14} />
        </Link>
        <Link
          to="/contracts"
          className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-slate-100 dark:bg-slate-700 text-sm font-medium text-slate-800 dark:text-slate-200 hover:bg-slate-200 dark:hover:bg-slate-600"
        >
          Hợp đồng <ArrowRight size={14} />
        </Link>
        <Link
          to="/finance"
          className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-slate-100 dark:bg-slate-700 text-sm font-medium text-slate-800 dark:text-slate-200 hover:bg-slate-200 dark:hover:bg-slate-600"
        >
          Tài chính &amp; ROI <ArrowRight size={14} />
        </Link>
        <Link
          to="/dashboard-project"
          className="inline-flex items-center gap-2 px-4 py-2 rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-900/20 text-sm font-medium text-blue-800 dark:text-blue-200"
        >
          Tổng quan theo dự án đang chọn <ArrowRight size={14} />
        </Link>
      </div>
    </div>
  );
};

export default Dashboard;
