import React from 'react';
import {
  Printer,
  Tag,
  TrendingUp,
  FileText,
  Users,
  UserCircle,
  Package,
  MapPin,
  ArrowUpRight,
  ArrowDownRight,
} from 'lucide-react';
import { toast } from 'sonner';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '../ui/card';
import { Button } from '../ui/button';
import { Badge } from '../ui/badge';
import { Skeleton } from '../ui/skeleton';
import {
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  LineChart,
  Line,
  PieChart,
  Pie,
  Cell,
  XAxis,
  YAxis,
} from 'recharts';
import { getDashboardOverview } from '../../services/dashboardService';
import { getTemplatePrintStatList } from '../../services/reportsService';
import type { DashboardMetricCardDto, DashboardOverviewDto, DashboardRecentLabelItemDto } from '../../types/dashboardOverview';
import type { TemplatePrintStatListItem } from '../../types/reports';
import { useAuth } from '../auth/AuthProvider';
import { displayNameFromUser } from '../../lib/currentUserDisplay';
import { formatRelativeSince } from '../../lib/relativeSince';

const CATEGORY_CHART_COLORS = ['#3b82f6', '#f59e0b', '#6366f1', '#10b981', '#ec4899', '#8b5cf6', '#14b8a6'];

function recentLabelBadgeText(item: DashboardRecentLabelItemDto): string {
  const b = (item.labelTypeBadge || '').trim();
  if (b && b !== '—') return b.length >= 2 ? b.slice(0, 2) : `${b} `.slice(0, 2);
  const d = (item.displayName || '').trim();
  if (d && d !== '—') return d.slice(0, 2);
  return 'LB';
}

function isRecentLabelExpired(item: DashboardRecentLabelItemDto): boolean {
  return (item.status || '').toLowerCase() === 'expired';
}

/** 与 reports template-print-stat 默认区间一致：近 30 天（含今天） */
function last30DaysIsoRange(): { startDate: string; endDate: string } {
  const end = new Date();
  const start = new Date();
  start.setHours(12, 0, 0, 0);
  end.setHours(12, 0, 0, 0);
  start.setDate(start.getDate() - 29);
  return {
    startDate: start.toISOString().slice(0, 10),
    endDate: end.toISOString().slice(0, 10),
  };
}

function formatHeaderDate(iso: string | null | undefined): string {
  const d = iso ? new Date(iso) : new Date();
  if (!Number.isFinite(d.getTime())) return new Date().toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
  return d.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
}

function formatTrendPrinted(m: DashboardMetricCardDto): string {
  const r = m.changeRate;
  const sign = r > 0 ? '+' : '';
  return `${sign}${r.toFixed(1)}%`;
}

function formatTrendNewCount(m: DashboardMetricCardDto): string {
  const v = m.changeValue;
  if (v === 0) return 'No change';
  return `${v > 0 ? '+' : ''}${v} New`;
}

function formatTrendActiveUsers(m: DashboardMetricCardDto): string {
  if (m.changeValue === 0) return 'Stable';
  return `${m.changeValue > 0 ? '+' : ''}${m.changeValue} New`;
}

function trendUpPrinted(m: DashboardMetricCardDto): boolean {
  return m.changeRate > 0 || (m.changeRate === 0 && m.changeValue >= 0);
}

function trendUpDelta(m: DashboardMetricCardDto): boolean {
  return m.changeValue >= 0;
}

function buildWeeklyChartSeries(overview: DashboardOverviewDto): { day: string; labels: number; date: string }[] {
  const pts = overview.weeklyPrintVolume ?? [];
  if (pts.length) {
    return pts.map((p) => ({
      date: p.date,
      day: new Date(`${p.date}T12:00:00`).toLocaleDateString('en-US', { weekday: 'short' }),
      labels: p.value,
    }));
  }
  const out: { day: string; labels: number; date: string }[] = [];
  for (let i = 6; i >= 0; i--) {
    const d = new Date();
    d.setHours(12, 0, 0, 0);
    d.setDate(d.getDate() - i);
    const iso = d.toISOString().slice(0, 10);
    out.push({
      date: iso,
      day: d.toLocaleDateString('en-US', { weekday: 'short' }),
      labels: 0,
    });
  }
  return out;
}

type KPICardProps = {
  title: string;
  value: string;
  trend: string;
  trendUp: boolean;
  icon: React.ComponentType<{ className?: string }>;
  color: string;
  bgColor: string;
};

export type DashboardProps = {
  /** 跳转 Reports 并选中 Label Report 标签页 */
  onViewReports?: () => void;
  /** Recent Labels 区域的 View All：跳转到 Reports 页面 */
  onViewAllRecentLabels?: () => void;
};

export function Dashboard({ onViewReports, onViewAllRecentLabels }: DashboardProps = {}) {
  const auth = useAuth();
  const welcomeName = auth.roleDisplay ?? displayNameFromUser(auth.user);
  const [overview, setOverview] = React.useState<DashboardOverviewDto | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [templateStats, setTemplateStats] = React.useState<TemplatePrintStatListItem[]>([]);
  const [templateStatsLoading, setTemplateStatsLoading] = React.useState(true);

  const load = React.useCallback(async () => {
    setLoading(true);
    setTemplateStatsLoading(true);
    const { startDate, endDate } = last30DaysIsoRange();
    try {
      const [data, statRes] = await Promise.all([
        getDashboardOverview(),
        getTemplatePrintStatList({
          skipCount: 1,
          maxResultCount: 12,
          startDate,
          endDate,
          sorting: 'PrintedCount desc',
        }).catch((e) => {
          console.error(e);
          return { items: [], totalCount: 0 };
        }),
      ]);
      setOverview(data);
      setTemplateStats(statRes.items ?? []);
    } catch (e) {
      console.error(e);
      toast.error(e instanceof Error ? e.message : 'Failed to load dashboard');
      setOverview(null);
      setTemplateStats([]);
    } finally {
      setLoading(false);
      setTemplateStatsLoading(false);
    }
  }, []);

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

  const weeklySeries = React.useMemo(() => (overview ? buildWeeklyChartSeries(overview) : []), [overview]);

  const pieRows = React.useMemo(() => {
    if (!overview?.byCategory?.length) return [];
    return overview.byCategory.map((c, i) => ({
      id: c.categoryId || `cat-${i}`,
      name: c.categoryName || '—',
      value: c.count,
      color: CATEGORY_CHART_COLORS[i % CATEGORY_CHART_COLORS.length],
    }));
  }, [overview]);

  const recentLabels = overview?.recentLabels ?? [];

  const categoryTotal = overview?.byCategoryTotal ?? 0;

  const generatedAt = overview?.generatedAt;

  return (
    <div className="space-y-6">
      <div className="bg-white border border-gray-200 p-4 rounded-xl shadow-sm flex flex-col md:flex-row justify-between items-center gap-4">
        <div>
          <h1 className="text-xl font-bold text-gray-900">Dashboard Overview</h1>
          <p className="text-sm text-gray-500">
            Welcome back, {welcomeName}. Here&apos;s what&apos;s happening today.
          </p>
          <p className="text-xs text-gray-400 mt-1">
            {formatHeaderDate(generatedAt)} | Last updated:{' '}
            {auth.loading && !auth.user?.lastUpdated
              ? '…'
              : formatRelativeSince(auth.user?.lastUpdated ?? generatedAt ?? null)}
          </p>
        </div>
        <div className="flex items-center gap-3">
          <Button type="button" variant="outline" onClick={() => onViewReports?.()}>
            View Reports
          </Button>
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        {loading || !overview ? (
          <>
            {Array.from({ length: 6 }).map((_, i) => (
              <Card key={i} className="border-gray-200 shadow-sm">
                <CardContent className="p-6 space-y-3">
                  <Skeleton className="h-4 w-32" />
                  <Skeleton className="h-8 w-20" />
                  <Skeleton className="h-4 w-40" />
                </CardContent>
              </Card>
            ))}
          </>
        ) : (
          <>
            <KPICard
              title={overview.labelsPrintedToday.title || 'Labels Printed Today'}
              value={String(overview.labelsPrintedToday.value)}
              trend={formatTrendPrinted(overview.labelsPrintedToday)}
              trendUp={trendUpPrinted(overview.labelsPrintedToday)}
              icon={Printer}
              color="text-blue-600"
              bgColor="bg-blue-50"
            />
            <KPICard
              title={overview.activeTemplates.title || 'Active Templates'}
              value={String(overview.activeTemplates.value)}
              trend={formatTrendNewCount(overview.activeTemplates)}
              trendUp={trendUpDelta(overview.activeTemplates)}
              icon={FileText}
              color="text-indigo-600"
              bgColor="bg-indigo-50"
            />
            <KPICard
              title={overview.activeUsers.title || 'Active Users'}
              value={String(overview.activeUsers.value)}
              trend={formatTrendActiveUsers(overview.activeUsers)}
              trendUp={trendUpDelta(overview.activeUsers)}
              icon={Users}
              color="text-emerald-600"
              bgColor="bg-emerald-50"
            />
            <KPICard
              title={overview.locations.title || 'Locations'}
              value={String(overview.locations.value)}
              trend={formatTrendNewCount(overview.locations)}
              trendUp={trendUpDelta(overview.locations)}
              icon={MapPin}
              color="text-sky-600"
              bgColor="bg-sky-50"
            />
            <KPICard
              title={overview.people.title || 'People'}
              value={String(overview.people.value)}
              trend={formatTrendNewCount(overview.people)}
              trendUp={trendUpDelta(overview.people)}
              icon={UserCircle}
              color="text-violet-600"
              bgColor="bg-violet-50"
            />
            <KPICard
              title={overview.products.title || 'Products'}
              value={String(overview.products.value)}
              trend={formatTrendNewCount(overview.products)}
              trendUp={trendUpDelta(overview.products)}
              icon={Package}
              color="text-amber-600"
              bgColor="bg-amber-50"
            />
          </>
        )}
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        <div className="lg:col-span-2 space-y-6">
          <Card className="shadow-sm border-gray-200">
            <CardHeader>
              <CardTitle className="text-base font-bold text-gray-800 flex items-center gap-2">
                <TrendingUp className="w-5 h-5 text-gray-500" />
                Weekly Print Volume
              </CardTitle>
              <CardDescription>Number of labels printed over the last 7 days</CardDescription>
            </CardHeader>
            <CardContent>
              {loading ? (
                <div className="h-[300px] w-full flex items-center justify-center">
                  <Skeleton className="h-[240px] w-full" />
                </div>
              ) : (
                <div className="h-[300px] w-full">
                  <ResponsiveContainer width="100%" height="100%">
                    <LineChart data={weeklySeries}>
                      <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#e5e7eb" />
                      <XAxis
                        dataKey="day"
                        axisLine={false}
                        tickLine={false}
                        tick={{ fill: '#6b7280', fontSize: 12 }}
                        dy={10}
                      />
                      <YAxis axisLine={false} tickLine={false} tick={{ fill: '#6b7280', fontSize: 12 }} />
                      <Tooltip
                        labelFormatter={(_, payload) => {
                          const p = payload?.[0]?.payload as { date?: string } | undefined;
                          return p?.date ?? '';
                        }}
                        contentStyle={{
                          borderRadius: '8px',
                          border: 'none',
                          boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)',
                        }}
                        cursor={{ stroke: '#d1d5db', strokeWidth: 1 }}
                      />
                      <Line
                        type="monotone"
                        dataKey="labels"
                        stroke="#2563eb"
                        strokeWidth={3}
                        dot={{ r: 4, fill: '#2563eb', strokeWidth: 2, stroke: '#fff' }}
                        activeDot={{ r: 6 }}
                      />
                    </LineChart>
                  </ResponsiveContainer>
                </div>
              )}
            </CardContent>
          </Card>

          <Card className="shadow-sm border-gray-200">
            <CardHeader className="flex flex-row items-center justify-between">
              <div>
                <CardTitle className="text-base font-bold text-gray-800 flex items-center gap-2">
                  <Tag className="w-5 h-5 text-gray-500" />
                  Recent Labels
                </CardTitle>
                <CardDescription>Latest printed labels across all locations</CardDescription>
              </div>
              <Button
                type="button"
                variant="ghost"
                size="sm"
                className="text-blue-600"
                onClick={() => onViewAllRecentLabels?.()}
              >
                View All
              </Button>
            </CardHeader>
            <CardContent>
              {loading ? (
                <div className="space-y-4">
                  {Array.from({ length: 5 }).map((_, i) => (
                    <div key={i} className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-100">
                      <div className="flex items-center gap-3 w-full">
                        <Skeleton className="h-10 w-10 rounded-full shrink-0" />
                        <div className="space-y-2 flex-1 min-w-0">
                          <Skeleton className="h-4 w-2/3 max-w-xs" />
                          <Skeleton className="h-3 w-1/2 max-w-sm" />
                        </div>
                        <div className="flex items-center gap-4 shrink-0">
                          <Skeleton className="h-3 w-16" />
                          <Skeleton className="h-6 w-16 rounded-md" />
                        </div>
                      </div>
                    </div>
                  ))}
                </div>
              ) : recentLabels.length === 0 ? (
                <div className="py-10 text-center text-sm text-gray-500">No recent labels. Printed labels will appear here.</div>
              ) : (
                <div className="space-y-4">
                  {recentLabels.map((label, i) => {
                    const expired = isRecentLabelExpired(label);
                    return (
                      <div
                        key={`${label.taskId}-${i}`}
                        className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-100 hover:bg-gray-100 transition-colors"
                      >
                        <div className="flex items-center gap-3 min-w-0 flex-1">
                          <div
                            className="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-bold text-xs shrink-0"
                            title={label.labelTypeBadge || undefined}
                          >
                            {recentLabelBadgeText(label)}
                          </div>
                          <div className="min-w-0">
                            <p className="text-sm font-semibold text-gray-900 truncate">{label.displayName || '—'}</p>
                            <p className="text-xs text-gray-500 truncate">
                              {label.labelCode || '—'} • {label.printedByName || '—'}
                            </p>
                          </div>
                        </div>
                        <div className="flex items-center gap-4 shrink-0 ml-2">
                          <span className="text-xs text-gray-500 font-medium whitespace-nowrap">
                            {formatRelativeSince(label.printedAt || null)}
                          </span>
                          <Badge
                            variant="secondary"
                            className={expired ? 'bg-red-100 text-red-700' : 'bg-green-100 text-green-700'}
                          >
                            {label.status || '—'}
                          </Badge>
                        </div>
                      </div>
                    );
                  })}
                </div>
              )}
            </CardContent>
          </Card>
        </div>

        <div className="space-y-6">
          <Card className="shadow-sm border-gray-200">
            <CardHeader>
              <CardTitle className="text-base font-bold text-gray-800 flex items-center gap-2">
                <Package className="w-5 h-5 text-gray-500" />
                By Category
              </CardTitle>
            </CardHeader>
            <CardContent>
              {loading ? (
                <div className="h-[200px] w-full flex items-center justify-center">
                  <Skeleton className="h-[160px] w-[160px] rounded-full" />
                </div>
              ) : pieRows.length === 0 ? (
                <div className="h-[200px] flex flex-col items-center justify-center text-sm text-gray-500">
                  No category distribution
                </div>
              ) : (
                <>
                  <div className="h-[200px] relative">
                    <ResponsiveContainer width="100%" height="100%">
                      <PieChart>
                        <Pie
                          data={pieRows}
                          cx="50%"
                          cy="50%"
                          innerRadius={60}
                          outerRadius={80}
                          paddingAngle={5}
                          dataKey="value"
                        >
                          {pieRows.map((entry, index) => (
                            <Cell key={`cell-${index}`} fill={entry.color} />
                          ))}
                        </Pie>
                        <Tooltip />
                      </PieChart>
                    </ResponsiveContainer>
                    <div className="absolute inset-0 flex items-center justify-center flex-col pointer-events-none">
                      <span className="text-2xl font-bold text-gray-900">{categoryTotal}</span>
                      <span className="text-xs text-gray-500">Total</span>
                    </div>
                  </div>
                  <div className="mt-4 space-y-2">
                    {pieRows.map((item) => (
                      <div key={item.id} className="flex items-center justify-between text-sm">
                        <div className="flex items-center gap-2">
                          <div className="w-3 h-3 rounded-full" style={{ backgroundColor: item.color }} />
                          <span className="text-gray-600">{item.name}</span>
                        </div>
                        <span className="font-medium text-gray-900">{item.value}</span>
                      </div>
                    ))}
                  </div>
                </>
              )}
            </CardContent>
          </Card>

          <Card className="shadow-sm border-gray-200">
            <CardHeader>
              <CardTitle className="text-base font-bold text-gray-800 flex items-center gap-2">
                <FileText className="w-5 h-5 text-gray-500" />
                Template Print Statistics
              </CardTitle>
              <CardDescription>By template — labels printed in the last 30 days</CardDescription>
            </CardHeader>
            <CardContent>
              {loading || templateStatsLoading ? (
                <div className="space-y-3">
                  {Array.from({ length: 6 }).map((_, i) => (
                    <div key={i} className="flex items-center justify-between gap-3">
                      <Skeleton className="h-4 flex-1 max-w-[200px]" />
                      <Skeleton className="h-4 w-12 shrink-0" />
                    </div>
                  ))}
                </div>
              ) : templateStats.length === 0 ? (
                <div className="py-10 text-center text-sm text-gray-500">
                  No template print data in the last 30 days.
                </div>
              ) : (
                <div className="space-y-2 max-h-[320px] overflow-y-auto pr-1">
                  {templateStats.map((row, i) => {
                    const name = (row.templateName ?? '').trim() || 'None';
                    const key = row.templateId ? `${row.templateId}-${i}` : `row-${i}-${name}`;
                    return (
                      <div
                        key={key}
                        className="flex items-center justify-between gap-3 py-2.5 px-3 rounded-lg border border-gray-100 bg-gray-50 hover:bg-gray-100 transition-colors"
                      >
                        <p className="text-sm font-medium text-gray-900 truncate min-w-0 flex-1" title={name}>
                          {name}
                        </p>
                        <span className="text-sm font-semibold text-gray-900 tabular-nums shrink-0">
                          {row.printedCount.toLocaleString()}
                        </span>
                      </div>
                    );
                  })}
                </div>
              )}
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}

function KPICard({ title, value, trend, trendUp, icon: Icon, color, bgColor }: KPICardProps) {
  return (
    <Card className="border-gray-200 shadow-sm hover:shadow-md transition-shadow">
      <CardContent className="p-6">
        <div className="flex justify-between items-start">
          <div>
            <p className="text-sm font-medium text-gray-500 mb-1">{title}</p>
            <h3 className="text-2xl font-bold text-gray-900">{value}</h3>
          </div>
          <div className={`p-2 rounded-lg ${bgColor}`}>
            <Icon className={`w-5 h-5 ${color}`} />
          </div>
        </div>
        <div className="mt-4 flex items-center text-sm">
          {trendUp ? (
            <ArrowUpRight className="w-4 h-4 text-green-500 mr-1 shrink-0" />
          ) : (
            <ArrowDownRight className="w-4 h-4 text-red-500 mr-1 shrink-0" />
          )}
          <span className={trendUp ? 'text-green-600 font-medium' : 'text-red-600 font-medium'}>{trend}</span>
          <span className="text-gray-400 ml-1">Vs. last period</span>
        </div>
      </CardContent>
    </Card>
  );
}
