import { useState, useEffect, useRef } from 'react'
import { Link } from 'react-router-dom'
import api from '../api'
import toast from 'react-hot-toast'
import { Users, AlertTriangle, Clock, CheckCircle, XCircle, Calendar, TrendingUp, ArrowRight, Award, AlertCircle, Clock3, Download, FileSpreadsheet, FileBarChart } from 'lucide-react'

export default function Dashboard() {
  const [summary, setSummary] = useState(null)
  const [stats, setStats] = useState(null)
  const [loading, setLoading] = useState(true)
  const [dateFrom, setDateFrom] = useState('')
  const [dateTo, setDateTo] = useState('')
  const [exporting, setExporting] = useState(false)
  const pieRef = useRef(null)
  const barRef = useRef(null)
  const pieChart = useRef(null)
  const barChart = useRef(null)
  const dashboardRef = useRef(null)

  useEffect(() => {
    fetchData()
  }, [dateFrom, dateTo])

  useEffect(() => {
    return () => {
      if (pieChart.current) pieChart.current.destroy()
      if (barChart.current) barChart.current.destroy()
    }
  }, [])

  useEffect(() => {
    if (summary && stats && !loading) {
      renderCharts()
    }
  }, [summary, stats, loading])

  const fetchData = async () => {
    setLoading(true)
    try {
      const params = {}
      if (dateFrom) params.date_from = dateFrom
      if (dateTo) params.date_to = dateTo

      const [sumRes, statRes] = await Promise.all([
        api.get('/api/dashboard/summary', { params }),
        api.get('/api/attendance/stats', { params }).catch(() => ({ data: null }))
      ])
      setSummary(sumRes.data)
      setStats(statRes.data)
    } catch (err) {
      toast.error('載入失敗')
      console.error(err)
    } finally {
      setLoading(false)
    }
  }

  const renderCharts = () => {
    if (!summary) return
    if (pieChart.current) pieChart.current.destroy()
    if (barChart.current) barChart.current.destroy()

    const Chart = window.Chart
    if (!Chart) return

    const pieCtx = pieRef.current?.getContext('2d')
    if (pieCtx) {
      const statusData = [
        { label: '正常', value: summary.normal_count || 0, color: '#10B981' },
        { label: '遲到', value: summary.late_count || 0, color: '#F59E0B' },
        { label: '早退', value: summary.early_count || 0, color: '#3B82F6' },
        { label: 'OT', value: summary.ot_count || 0, color: '#8B5CF6' },
        { label: '異常', value: summary.abnormal_count || 0, color: '#EF4444' },
        { label: '缺勤', value: summary.missing_count || 0, color: '#6B7280' },
      ].filter(s => s.value > 0)

      if (statusData.length > 0) {
        pieChart.current = new Chart(pieCtx, {
          type: 'doughnut',
          data: {
            labels: statusData.map(s => s.label),
            datasets: [{ data: statusData.map(s => s.value), backgroundColor: statusData.map(s => s.color), borderWidth: 2, borderColor: '#fff' }]
          },
          options: {
            responsive: true, maintainAspectRatio: false,
            plugins: { legend: { position: 'bottom', labels: { padding: 16, font: { size: 12 } } }, title: { display: true, text: '出勤狀態分佈', font: { size: 14, weight: '600' }, padding: { bottom: 12 } } }
          }
        })
      }
    }

    const barCtx = barRef.current?.getContext('2d')
    if (barCtx && stats?.stats?.length > 0) {
      const staffData = stats.stats.slice(0, 8)
      barChart.current = new Chart(barCtx, {
        type: 'bar',
        data: {
          labels: staffData.map(s => s.name),
          datasets: [{ label: '出勤記錄', data: staffData.map(s => s.total_records || s.total || 0), backgroundColor: '#2563EB', borderRadius: 4 }]
        },
        options: {
          responsive: true, maintainAspectRatio: false,
          plugins: { legend: { display: false }, title: { display: true, text: '員工出勤記錄數', font: { size: 14, weight: '600' }, padding: { bottom: 12 } } },
          scales: { y: { beginAtZero: true, ticks: { stepSize: 1 } } }
        }
      })
    }
  }

  // Export PDF - capture dashboard as image then make PDF
  const exportPDF = async () => {
    if (!dashboardRef.current) { toast.error('找不到 Dashboard'); return }
    setExporting(true)
    try {
      if (typeof window.jspdf === 'undefined') throw new Error('jspdf 未載入')
      if (typeof window.Chart === 'undefined') throw new Error('Chart.js 未載入')

      const { jsPDF } = window.jspdf
      const pdf = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' })
      const PW = pdf.internal.pageSize.getWidth()  // 297mm
      const PH = pdf.internal.pageSize.getHeight()  // 210mm
      const M = 12

      // ─── Title ───
      pdf.setFontSize(18); pdf.setTextColor(15,23,42)
      pdf.text('Attendance Report', M, 14)
      const range = (dateFrom || dateTo) ? `${dateFrom||'開始'} ~ ${dateTo||'今日'}` : '全部'
      const now = new Date().toLocaleString('en-US',{hour12:false,year:'numeric',month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit'})
      pdf.setFontSize(9); pdf.setTextColor(100,116,139)
      pdf.text(`Date Range: ${range}  |  Generated: ${now}`, M, 20)

      // ─── Summary Cards ───
      const cards = summary ? [
        { label: 'Total', value: summary.total_records, color: [37,99,235] },
        { label: 'Normal', value: summary.normal_count, color: [16,185,129] },
        { label: 'Late', value: summary.late_count, color: [245,158,11] },
        { label: 'OT', value: summary.ot_count, color: [139,92,246] },
        { label: 'Abnormal', value: summary.abnormal_count, color: [239,68,68] },
        { label: 'Missing', value: summary.missing_count, color: [107,114,128] },
      ] : []

      const cardW = (PW - M*2) / cards.length - 3
      cards.forEach((card, i) => {
        const cx = M + i*(cardW+3)
        pdf.setFillColor(...card.color)
        pdf.roundedRect(cx, 22, cardW, 16, 2, 2, 'F')
        pdf.setFontSize(14); pdf.setTextColor(255,255,255)
        pdf.text(String(card.value ?? 0), cx+cardW/2, 30, {align:'center'})
        pdf.setFontSize(7); pdf.setTextColor(255,255,255)
        pdf.text(card.label, cx+cardW/2, 34, {align:'center'})
      })

      // ─── Charts ───
      const chartTop = 44
      const chartH = 60
      const chartW = (PW - M*2 - 8) / 2  // two charts side by side

      // Helper: draw doughnut / pie chart
      const drawPieChart = (cx, cy, r, data, colors, pdf) => {
        const total = data.reduce((a,b)=>a+b, 0)
        if (total === 0) return
        let angle = -Math.PI/2
        data.forEach((val, i) => {
          const slice = (val/total) * 2*Math.PI
          pdf.setFillColor(...colors[i])
          pdf.setDrawColor(255,255,255)
          pdf.setLineWidth(0.3)
          const x1 = cx + r * Math.cos(angle)
          const y1 = cy + r * Math.sin(angle)
          const x2 = cx + r * Math.cos(angle + slice)
          const y2 = cy + r * Math.sin(angle + slice)
          if (val === total) {
            pdf.setFillColor(...colors[i])
            pdf.circle(cx, cy, r, 'F')
          } else {
            const pts = [[cx, cy], [x1, y1], [x2, y2]]
            pdf.triangle(pts[0][0], pts[0][1], pts[1][0], pts[1][1], pts[2][0], pts[2][1], 'F')
          }
          angle += slice
        })
        // inner circle (donut hole)
        pdf.setFillColor(255,255,255)
        pdf.circle(cx, cy, r*0.5, 'F')
      }

      // Helper: draw bar chart
      const drawBarChart = (bx, by, bw, bh, labels, values, barColor, pdf) => {
        const max = Math.max(...values, 1)
        const barW = bw / labels.length * 0.6
        const gap = bw / labels.length * 0.4
        labels.forEach((lbl, i) => {
          const barH = (values[i]/max) * bh
          const x = bx + i*(barW+gap) + gap/2
          const y = by + bh - barH
          pdf.setFillColor(...barColor)
          pdf.roundedRect(x, y, barW, barH, 1, 1, 'F')
          // value label
          pdf.setFontSize(6); pdf.setTextColor(100,116,139)
          pdf.text(String(values[i]), x+barW/2, by+bh+3.5, {align:'center'})
          // x label (truncated)
          pdf.setFontSize(6); pdf.setTextColor(100,116,139)
          pdf.text(lbl.length > 6 ? lbl.substring(0,5)+'.' : lbl, x+barW/2, by+bh+6.5, {align:'center'})
        })
      }

      // ── Pie: 出勤狀態分佈 ──
      if (summary) {
        const pieCX = M + chartW/2
        const pieCY = chartTop + chartH/2
        const pieR = chartH/2 - 4
        const pieData = [
          summary.normal_count || 0,
          summary.late_count || 0,
          summary.early_count || 0,
          summary.ot_count || 0,
          summary.abnormal_count || 0,
          summary.missing_count || 0,
        ]
        const pieColors = [[16,185,129],[245,158,11],[59,130,246],[139,92,246],[239,68,68],[107,114,128]]
        const pieLabels = ['Normal','Late','Early','OT','Abnormal','Missing']
        const pieLegendX = M
        const pieLegendY = chartTop + chartH + 5

        pdf.setFontSize(10); pdf.setTextColor(15,23,42)
        pdf.text('Attendance Status Distribution', M, chartTop - 2)

        // Draw pie
        drawPieChart(pieCX, pieCY, pieR, pieData, pieColors, pdf)

        // Legend
        let lx = M
        pieLabels.forEach((lbl, i) => {
          if (pieData[i] === 0) return
          pdf.setFillColor(...pieColors[i])
          pdf.rect(lx, pieLegendY, 4, 4, 'F')
          pdf.setFontSize(7.5); pdf.setTextColor(60,70,90)
          pdf.text(`${lbl} ${pieData[i]}`, lx+5, pieLegendY+3.5)
          lx += 28
        })
      }

      // ── Bar: 員工出勤記錄 ──
      if (stats?.stats?.length > 0) {
        const barX = M + chartW + 8
        const barLabels = stats.stats.slice(0,8).map(s=>s.name)
        const barValues = stats.stats.slice(0,8).map(s=>s.total_records || s.total || 0)

        pdf.setFontSize(10); pdf.setTextColor(15,23,42)
        pdf.text('Staff Attendance Records', barX, chartTop - 2)

        // Axis
        const axisX = barX + 2
        const axisY = chartTop + chartH - 2
        const axisW = chartW - 4
        const axisH = chartH - 8
        pdf.setDrawColor(200,210,220)
        pdf.setLineWidth(0.3)
        pdf.line(axisX, axisY, axisX, axisY - axisH)  // y axis
        pdf.line(axisX, axisY, axisX + axisW, axisY)   // x axis

        drawBarChart(axisX, axisY - axisH, axisW, axisH, barLabels, barValues, [37,99,235], pdf)
      }

      // ─── Leaderboards ───
      if (stats?.stats?.length > 0) {
        const staff = stats.stats
        const lbTop = chartTop + chartH + 14
        const lateRank = [...staff].sort((a,b)=>(b.late_count||0)-(a.late_count||0)).slice(0,5)
        const otRank = [...staff].sort((a,b)=>(b.ot_count||0)-(a.ot_count||0)).slice(0,5)
        const missRank = [...staff].sort((a,b)=>(b.missing_count||0)-(a.missing_count||0)).slice(0,5)
        const rateRank = [...staff].map(s=>({...s,rate:(s.total_records||s.total||0)>0?Math.round((((s.total_records||s.total||0)-(s.late_count||0)-(s.abnormal_count||0))/(s.total_records||s.total||0))*100):0})).sort((a,b)=>b.rate-a.rate).slice(0,5)

        const lbW = (PW - M*2) / 4 - 4
        const lbData = [
          { title: 'Late Rank', data: lateRank, key: 'late_count', sub: 'late_minutes', color: [245,158,11] },
          { title: 'OT Rank', data: otRank, key: 'ot_count', sub: 'ot_minutes', color: [139,92,246] },
          { title: 'Missing Rank', data: missRank, key: 'missing_count', sub: null, color: [107,114,128] },
          { title: 'Attendance Rate', data: rateRank, key: 'rate', sub: null, color: [16,185,129] },
        ]

        lbData.forEach((lb, li) => {
          const lx = M + li*(lbW+4)
          // Box
          pdf.setFillColor(...lb.color)
          pdf.roundedRect(lx, lbTop, lbW, 6, 2, 2, 'F')
          pdf.setFontSize(8); pdf.setTextColor(255,255,255)
          const lines = lb.title.split('\n')
          lines.forEach((l, li2) => pdf.text(l, lx+lbW/2, lbTop+3+li2*3, {align:'center'}))
          // Items
          lb.data.forEach((item, di) => {
            const iy = lbTop + 10 + di*5
            const medal = ['🥇','🥈','🥉'][di] || ` ${di+1}.`
            const sub = lb.sub && item[lb.sub] ? ` (${item[lb.sub]}min)` : ''
            const val = `${item[lb.key]}${lb.key==='rate'?'%':''}${sub}`
            pdf.setFontSize(7.5); pdf.setTextColor(30,41,59)
            pdf.text(`${medal} ${item.name} ${val}`, lx+2, iy)
          })
        })
      }

      // ─── Staff Table ───
      if (stats?.stats?.length > 0) {
        const tblTop = PW > 250 ? (chartTop + chartH + 14 + 35) : (chartTop + chartH + 14 + 30)
        pdf.setFontSize(11); pdf.setTextColor(15,23,42)
        pdf.text('Staff Summary', M, tblTop - 1)

        const staff = stats.stats
        const colW = [46, 18, 16, 20, 16, 20, 16, 16]
        const cols = ['Name','Total','Late','LateMin','OT','OTMin','Abn','Miss']
        let xPos = [M]
        for (let ci=0; ci<colW.length-1; ci++) xPos.push(xPos[ci]+colW[ci])
        const rowH = 6

        // Header
        pdf.setFillColor(50,60,80)
        pdf.rect(M, tblTop, PW-M*2, rowH, 'F')
        pdf.setFontSize(8); pdf.setTextColor(255,255,255)
        cols.forEach((h,ci) => pdf.text(h, xPos[ci]+colW[ci]/2, tblTop+4.5, {align:'center'}))

        // Rows
        staff.forEach((s, ri) => {
          const ry = tblTop + rowH*(ri+1)
          if (ri%2===0) { pdf.setFillColor(248,250,252); pdf.rect(M, ry, PW-M*2, rowH, 'F') }
          pdf.setFontSize(8); pdf.setTextColor(30,41,59)
          const vals = [s.name, String(s.total_records || s.total || 0), String(s.late_count||0), String(s.late_minutes||'-'), String(s.ot_count||0), String(s.ot_minutes||'-'), String(s.abnormal_count||0), String(s.missing_count||0)]
          vals.forEach((v,ci) => pdf.text(v, xPos[ci]+colW[ci]/2, ry+4.5, {align:'center'}))
        })
      }

      pdf.save(`attendance_report_${dateFrom||'all'}_${dateTo||''}.pdf`.replace(/-/g,''))
      toast.success('✅ PDF 已下載')
    } catch (err) {
      console.error('PDF error:', err)
      toast.error('PDF 導出失敗: ' + err.message)
    } finally {
      setExporting(false)
    }
  }

  const exportExcel = async (full) => {
    setExporting(true)
    try {
      const token = localStorage.getItem('aars_token')
      const params = full ? {} : (dateFrom ? { date_from: dateFrom, date_to: dateTo || new Date().toISOString().slice(0, 10) } : {})
      const url = `/api/export/attendance/excel${Object.keys(params).length ? '?' + new URLSearchParams(params).toString() : ''}`
      const resp = await fetch(url, { headers: { Authorization: `Bearer ${token}` } })
      if (!resp.ok) throw new Error('Export failed')
      const blob = await resp.blob()
      const filename = full
        ? `attendance_full.xlsx`
        : `attendance_${dateFrom || 'start'}_${dateTo || 'today'}.xlsx`.replace(/-/g, '')
      const a = document.createElement('a')
      a.href = URL.createObjectURL(blob)
      a.download = filename
      a.click()
      URL.revokeObjectURL(a.href)
      toast.success('✅ Excel 已下載')
    } catch (err) {
      console.error('Excel export error:', err)
      toast.error('Excel 導出失敗')
    } finally {
      setExporting(false)
    }
  }

  const byStaff = stats?.stats || []
  const lateRank = [...byStaff].sort((a, b) => (b.late_count || 0) - (a.late_count || 0))
  const otRank = [...byStaff].sort((a, b) => (b.ot_count || 0) - (a.ot_count || 0))
  const abnormalRank = [...byStaff].sort((a, b) => (b.abnormal_count || 0) - (a.abnormal_count || 0))
  const missingRank = [...byStaff].sort((a, b) => (b.missing_count || 0) - (a.missing_count || 0))
  const attendanceRate = [...byStaff].map(s => ({
    ...s,
    rate: (s.total_records || s.total || 0) > 0 ? Math.round(((((s.total_records || s.total || 0) - (s.late_count || 0) - (s.abnormal_count || 0))) / (s.total_records || s.total || 0)) * 100) : 0
  })).sort((a, b) => b.rate - a.rate)

  const statCards = summary ? [
    { label: '總記錄', value: summary.total_records, icon: Calendar, color: 'bg-blue-50 text-blue-600' },
    { label: '正常', value: summary.normal_count, icon: CheckCircle, color: 'bg-green-50 text-green-600' },
    { label: '遲到', value: summary.late_count, icon: Clock, color: 'bg-orange-50 text-orange-600' },
    { label: '早退', value: summary.early_count, icon: Clock3, color: 'bg-blue-50 text-blue-600' },
    { label: 'OT', value: summary.ot_count, icon: TrendingUp, color: 'bg-purple-50 text-purple-600' },
    { label: '異常', value: summary.abnormal_count, icon: AlertTriangle, color: 'bg-red-50 text-red-600' },
    { label: '缺勤', value: summary.missing_count, icon: XCircle, color: 'bg-gray-50 text-gray-600' },
    { label: '員工', value: summary.staff_count, icon: Users, color: 'bg-teal-50 text-teal-600' },
  ] : []

  const today = new Date().toISOString().slice(0, 10)
  const monthStart = new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString().slice(0, 10)

  // Date preset helpers
  const fmt = (d) => d.toISOString().slice(0, 10)
  const weekRange = (offsetWeeks) => {
    // Monday = start of week
    const now = new Date()
    const dow = now.getDay() // Sun=0, Mon=1, ... Sat=6
    const daysFromMonday = (dow + 6) % 7 // Mon=0, Tue=1, ..., Sun=6
    const start = new Date(now)
    start.setDate(now.getDate() - daysFromMonday + offsetWeeks * 7)
    const end = new Date(start)
    end.setDate(start.getDate() + 6)
    return [fmt(start), fmt(end)]
  }

  // Map rankKey to Option 1 detail fields exposed by backend
  const detailFieldsMap = {
    late_count: [
      { key: 'late_minutes', label: '分鐘', unit: '分' },
      { key: 'late_avg_minutes', label: '平均', unit: '分' },
      { key: 'late_max_minutes', label: '最長', unit: '分' },
    ],
    early_count: [
      { key: 'early_minutes', label: '分鐘', unit: '分' },
      { key: 'early_avg_minutes', label: '平均', unit: '分' },
      { key: 'early_max_minutes', label: '最長', unit: '分' },
    ],
    ot_count: [
      { key: 'ot_minutes', label: '分鐘', unit: '分' },
      { key: 'ot_avg_minutes', label: '平均', unit: '分' },
      { key: 'ot_max_minutes', label: '最長', unit: '分' },
    ],
    missing_count: [
      { key: 'consecutive_missing', label: '連續', unit: '次' },
      { key: 'attendance_rate', label: '出勤率', unit: '%', suffix: true },
      { key: 'last_attendance_date', label: '最後', isDate: true },
    ],
    rate: [
      { key: 'total_records', label: '記錄', unit: '條' },
      { key: 'missing_count', label: '缺勤', unit: '次' },
    ],
  }

  const RankCard = ({ title, icon: Icon, iconColor, data, rankKey, subKey, unit, colorFn }) => {
    const details = detailFieldsMap[rankKey] || []
    const items = data.filter(d => d[rankKey] > 0 || rankKey === 'rate').slice(0, 6)
    return (
      <div className="card p-4">
        <h3 className="text-sm font-semibold text-slate-700 mb-3 flex items-center gap-2">
          <Icon size={16} style={{ color: iconColor }} /> {title}
        </h3>
        <div className="space-y-1">
          {items.length === 0 ? (
            <p className="text-sm text-slate-400 text-center py-4">暫無數據</p>
          ) : items.map((s, i) => (
            <div key={s.name} className="py-1.5 border-b border-slate-100 last:border-0">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2">
                  <span className={`w-5 h-5 rounded-full flex items-center justify-center text-xs font-bold ${
                    i === 0 ? 'bg-yellow-100 text-yellow-700' : i === 1 ? 'bg-slate-100 text-slate-500' : i === 2 ? 'bg-orange-50 text-orange-400' : 'bg-slate-50 text-slate-400'
                  }`}>{i + 1}</span>
                  <span className="text-sm text-slate-700">{s.name}</span>
                </div>
                <div className="text-right">
                  <span className="text-sm font-bold" style={colorFn ? { color: colorFn(s) } : undefined}>
                    {rankKey === 'rate' ? `${s[rankKey]}%` : s[rankKey]}
                  </span>
                  {subKey && (s[subKey] || 0) > 0 && (
                    <span className="text-xs text-slate-400 ml-1">({s[subKey]}{unit || '次'})</span>
                  )}
                </div>
              </div>
              {/* Option 1 detail row */}
              {details.length > 0 && (
                <div className="flex flex-wrap gap-x-3 gap-y-0.5 mt-1 ml-7 text-[11px] text-slate-500">
                  {details.map(d => {
                    const v = s[d.key]
                    let display
                    if (v === null || v === undefined || v === 0 && d.key !== 'attendance_rate') {
                      // Skip empty/zero for most fields, but show 0% rate
                      if (!(d.key === 'attendance_rate')) return null
                      display = `0${d.unit}`
                    } else if (d.isDate) {
                      display = `${d.label} ${v}`
                    } else if (d.suffix) {
                      // e.g. attendance_rate = 70 (already %)
                      display = `${d.label} ${v}${d.unit}`
                    } else {
                      display = `${d.label} ${v}${d.unit}`
                    }
                    // For attendance_rate, only show if rate exists
                    if (d.key === 'attendance_rate' && (v === null || v === undefined)) return null
                    // For last_attendance_date, only show if exists
                    if (d.isDate && !v) return null
                    // For consecutive_missing, only show if > 0 (otherwise skip)
                    if (d.key === 'consecutive_missing' && (v || 0) === 0) return null
                    return <span key={d.key}>{display}</span>
                  })}
                </div>
              )}
            </div>
          ))}
        </div>
      </div>
    )
  }

  return (
    <div className="space-y-6" ref={dashboardRef}>
      {/* Header */}
      <div className="flex items-center justify-between">
        <h1 className="text-xl font-bold text-slate-900">Dashboard</h1>
        <div className="flex items-center gap-2">
          {/* Export Buttons */}
          <div className="flex items-center gap-1 border border-slate-300 rounded-md overflow-hidden">
            <button
              onClick={exportPDF}
              disabled={exporting}
              className="flex items-center gap-1 px-3 py-2 text-sm bg-white text-slate-700 hover:bg-slate-50 disabled:opacity-50"
              title="導出 PDF"
            >
              <FileBarChart size={14} /> PDF
            </button>
            <div className="w-px h-5 bg-slate-300" />
            <button
              onClick={() => exportExcel(false)}
              disabled={exporting}
              className="flex items-center gap-1 px-3 py-2 text-sm bg-white text-slate-700 hover:bg-slate-50 disabled:opacity-50"
              title="導出 Excel (跟時間範圍)"
            >
              <FileSpreadsheet size={14} /> Excel
            </button>
            <div className="w-px h-5 bg-slate-300" />
            <button
              onClick={() => exportExcel(true)}
              disabled={exporting}
              className="flex items-center gap-1 px-3 py-2 text-sm bg-blue-50 text-blue-700 hover:bg-blue-100 disabled:opacity-50 font-medium"
              title="導出 Excel (全部)"
            >
              <Download size={14} /> 全部
            </button>
          </div>
          <Link to="/attendance" className="flex items-center gap-2 px-4 py-2 bg-slate-100 text-slate-700 text-sm rounded-md hover:bg-slate-200">
            <ArrowRight size={16} /> 出勤記錄
          </Link>
        </div>
      </div>

      {/* Date Filter */}
      <div className="card p-4">
        <div className="flex flex-wrap gap-3 items-end">
          <div className="flex items-center gap-2">
            <span className="text-sm text-slate-500">日期範圍:</span>
            <input type="date" value={dateFrom} onChange={e => setDateFrom(e.target.value)} className="text-sm border border-slate-300 rounded-md px-3 py-2" />
            <span className="text-slate-400">-</span>
            <input type="date" value={dateTo} onChange={e => setDateTo(e.target.value)} className="text-sm border border-slate-300 rounded-md px-3 py-2" />
          </div>
          <div className="flex gap-2 flex-wrap">
            <button onClick={() => { setDateFrom(today); setDateTo(today) }} className="text-xs px-3 py-2 border border-slate-300 rounded-md hover:bg-slate-50">今日</button>
            <button onClick={() => {
              const [w0, w1] = weekRange(0)
              setDateFrom(w0); setDateTo(w1)
            }} className="text-xs px-3 py-2 border border-slate-300 rounded-md hover:bg-slate-50">本週</button>
            <button onClick={() => {
              const [w0, w1] = weekRange(-1)
              setDateFrom(w0); setDateTo(w1)
            }} className="text-xs px-3 py-2 border border-slate-300 rounded-md hover:bg-slate-50">上週</button>
            <button onClick={() => { setDateFrom(monthStart); setDateTo(today) }} className="text-xs px-3 py-2 border border-slate-300 rounded-md hover:bg-slate-50">本月</button>
            <button onClick={() => { setDateFrom(''); setDateTo('') }} className="text-xs text-slate-500 hover:text-slate-700 px-2 py-2 border border-slate-300 rounded">清除</button>
          </div>
        </div>
        {(dateFrom || dateTo) && (
          <p className="text-xs text-slate-400 mt-2">顯示 {dateFrom || '開始'} ~ {dateTo || today} 的數據</p>
        )}
      </div>

      {loading ? (
        <div className="text-center py-12 text-slate-400">載入中...</div>
      ) : summary ? (
        <>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {statCards.map(({ label, value, icon: Icon, color }) => (
              <div key={label} className="card p-4">
                <div className="flex items-center gap-3">
                  <div className={`p-2.5 rounded-lg ${color}`}><Icon size={20} /></div>
                  <div>
                    <div className="text-2xl font-bold text-slate-900">{value ?? 0}</div>
                    <div className="text-xs text-slate-500">{label}</div>
                  </div>
                </div>
              </div>
            ))}
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
            <div className="card p-4">
              <div style={{ height: '260px', position: 'relative' }}><canvas ref={pieRef}></canvas></div>
            </div>
            <div className="card p-4">
              <div style={{ height: '260px', position: 'relative' }}><canvas ref={barRef}></canvas></div>
            </div>
          </div>

          {byStaff.length > 0 && (
            <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
              <RankCard title="遲到排行榜" icon={Clock} iconColor="#F59E0B" data={lateRank} rankKey="late_count" subKey="late_minutes" unit="分" colorFn={s => s.late_count > 0 ? '#F59E0B' : '#10B981'} />
              <RankCard title="OT排行榜" icon={TrendingUp} iconColor="#8B5CF6" data={otRank} rankKey="ot_count" subKey="ot_minutes" unit="分" colorFn={s => s.ot_count > 0 ? '#8B5CF6' : '#10B981'} />
              <RankCard title="缺勤排行榜" icon={XCircle} iconColor="#6B7280" data={missingRank} rankKey="missing_count" colorFn={s => s.missing_count > 0 ? '#EF4444' : '#10B981'} />
              <RankCard title="出勤率排行榜" icon={Award} iconColor="#10B981" data={attendanceRate} rankKey="rate" colorFn={s => s.rate >= 90 ? '#10B981' : s.rate >= 70 ? '#F59E0B' : '#EF4444'} />
            </div>
          )}

          {stats?.stats?.length > 0 && (
            <div className="card p-4">
              <h2 className="text-sm font-semibold text-slate-700 mb-3 flex items-center gap-2">
                <Users size={16} /> 員工出勤概覽
              </h2>
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead className="bg-slate-50 border-b border-slate-200">
                    <tr>
                      <th className="px-3 py-2 text-left text-xs font-semibold text-slate-600">員工</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">出勤</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">正常</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">遲到</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">遲分鐘</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">OT</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">OT分鐘</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">異常</th>
                      <th className="px-3 py-2 text-right text-xs font-semibold text-slate-600">缺勤</th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-slate-100">
                    {byStaff.map((s) => (
                      <tr key={s.name} className="hover:bg-slate-50">
                        <td className="px-3 py-2 font-medium text-slate-700">{s.name}</td>
                        <td className="px-3 py-2 text-right text-slate-600">{s.total_records ?? s.total ?? 0}</td>
                        <td className="px-3 py-2 text-right text-green-600">{(s.total_records ?? s.total ?? 0) - (s.late_count || 0) - (s.abnormal_count || 0)}</td>
                        <td className="px-3 py-2 text-right text-orange-600">{s.late_count || 0}</td>
                        <td className="px-3 py-2 text-right text-orange-400">{s.late_minutes || '-'}</td>
                        <td className="px-3 py-2 text-right text-purple-600">{s.ot_count || 0}</td>
                        <td className="px-3 py-2 text-right text-purple-400">{s.ot_minutes || '-'}</td>
                        <td className="px-3 py-2 text-right text-red-600">{s.abnormal_count || 0}</td>
                        <td className="px-3 py-2 text-right text-gray-500">{s.missing_count || 0}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          )}
        </>
      ) : (
        <div className="text-center py-12 text-slate-400">暫無數據</div>
      )}
    </div>
  )
}
