import { useEffect, useMemo, useState } from 'react';
import { motion, AnimatePresence, useDragControls } from 'motion/react';
import { X, Truck } from 'lucide-react';
import {
  BarChart, Bar, XAxis, YAxis, ResponsiveContainer, Tooltip, Cell,
} from 'recharts';
import type { MileageSourceGroup, MonitoringVehicle } from './types';
import { fetchVehicleRecent, type VehicleRecentDay } from './api';
import Blur from '../../components/Blur';

interface Props {
  vehicle: MonitoringVehicle | null;
  onClose: () => void;
  sourcePriority: MileageSourceGroup[];
}

type RangeKey = 'last15' | 'month' | 'quarter';

const RANGE_TABS: { key: RangeKey; label: string }[] = [
  { key: 'last15', label: '近 15 天' },
  { key: 'month', label: '本月' },
  { key: 'quarter', label: '本季度' },
];

function fmtYmd(d: Date): string {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const dd = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${dd}`;
}

function rangeFor(key: RangeKey): { start: string; end: string; rangeLabel: string } {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const end = fmtYmd(today);
  if (key === 'last15') {
    const start = new Date(today);
    start.setDate(today.getDate() - 14);
    return { start: fmtYmd(start), end, rangeLabel: '近 15 天' };
  }
  if (key === 'month') {
    const start = new Date(today.getFullYear(), today.getMonth(), 1);
    return { start: fmtYmd(start), end, rangeLabel: '本月' };
  }
  const q = Math.floor(today.getMonth() / 3);
  const start = new Date(today.getFullYear(), q * 3, 1);
  return { start: fmtYmd(start), end, rangeLabel: '本季度' };
}

function isToday(date: string): boolean {
  return date === fmtYmd(new Date());
}

function formatLabel(date: string, key: RangeKey): string {
  // YYYY-MM-DD → MM-DD（季度时仍展示 MM-DD）
  void key;
  return date.slice(5);
}

function daySourceLabel(day: VehicleRecentDay): string {
  if (day.sourceCategory === 'INSTRUMENT') return '仪表数据';
  if (day.sourceCategory === 'GPS') return 'GPS数据';
  return day.isDataSynced ? '来源待接口' : '无数据';
}

export default function VehicleDetailModal({ vehicle, onClose, sourcePriority }: Props) {
  const [days, setDays] = useState<VehicleRecentDay[]>([]);
  const [loading, setLoading] = useState(false);
  const [range, setRange] = useState<RangeKey>('last15');
  const dragControls = useDragControls();

  // 切换车辆时重置区间为默认
  useEffect(() => {
    if (vehicle) setRange('last15');
  }, [vehicle?.plate]); // eslint-disable-line react-hooks/exhaustive-deps

  // 拉取数据（车辆或区间变化）
  useEffect(() => {
    if (!vehicle) return;
    const { start, end } = rangeFor(range);
    setLoading(true);
    setDays([]);
    let cancelled = false;
    fetchVehicleRecent(vehicle.plate, { start, end, sourcePriority })
      .then(d => { if (!cancelled) setDays(d.days); })
      .catch(() => { if (!cancelled) setDays([]); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [vehicle?.plate, range, sourcePriority]); // eslint-disable-line react-hooks/exhaustive-deps

  // 锁滚动
  useEffect(() => {
    if (!vehicle) return;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = ''; };
  }, [vehicle]);

  // 排除"今日"列（数据未到位时易引起误读）
  const historyDays = useMemo(() => days.filter(d => !isToday(d.date)), [days]);
  const stats = useMemo(() => {
    const totalKm = historyDays.reduce((s, d) => s + d.dailyKm, 0);
    const synced = historyDays.filter(d => d.isDataSynced).length;
    const avg = synced > 0 ? totalKm / synced : 0;
    const max = Math.max(1, ...historyDays.map(d => d.dailyKm));
    return { totalKm, synced, avg, max, totalDays: historyDays.length };
  }, [historyDays]);

  // 骨架天数：根据区间预估
  const skeletonCount = useMemo(() => {
    if (range === 'last15') return 15;
    const { start, end } = rangeFor(range);
    const s = new Date(start);
    const e = new Date(end);
    return Math.max(1, Math.round((e.getTime() - s.getTime()) / 86400000));
  }, [range]);

  return (
    <AnimatePresence>
      {vehicle && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          className="fixed inset-0 z-[80] bg-slate-900/40 backdrop-blur-sm flex items-end md:items-center justify-center"
          onClick={onClose}
        >
          <motion.div
            initial={{ y: '100%', opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            exit={{ y: '100%', opacity: 0 }}
            transition={{
              y: { type: 'spring', damping: 32, stiffness: 320 },
              opacity: { duration: 0.18 },
            }}
            drag="y"
            dragControls={dragControls}
            dragListener={false}
            dragConstraints={{ top: 0, bottom: 0 }}
            dragElastic={{ top: 0, bottom: 0.6 }}
            onDragEnd={(_, info) => {
              if (info.offset.y > 100 || info.velocity.y > 600) onClose();
            }}
            className="bg-white w-full md:max-w-md md:rounded-3xl rounded-t-3xl shadow-2xl max-h-[92vh] overflow-hidden flex flex-col touch-pan-y"
            onClick={(e) => e.stopPropagation()}
          >
            {/* iOS 风格 drag handle —— 长按下滑可关闭 */}
            <div
              className="flex justify-center pt-2.5 pb-1.5 cursor-grab active:cursor-grabbing select-none"
              onPointerDown={(e) => dragControls.start(e)}
              style={{ touchAction: 'none' }}
            >
              <div className="w-10 h-1 rounded-full bg-slate-300" />
            </div>

            {/* Header */}
            <div className="flex items-center justify-between px-4 pb-2 border-b border-slate-100">
              <div className="flex items-center gap-3 min-w-0">
                <div className="w-9 h-9 rounded-xl bg-blue-50 flex items-center justify-center flex-shrink-0">
                  <Truck size={16} className="text-blue-600" />
                </div>
                <div className="min-w-0">
                  <div className="flex items-center gap-1.5">
                    <span className="text-sm font-black text-slate-900 font-mono truncate"><Blur>{vehicle.plate}</Blur></span>
                    <span className={`text-[8px] px-1 rounded font-bold ${vehicle.isOnline ? 'bg-green-50 text-green-600' : 'bg-slate-100 text-slate-400'}`}>
                      {vehicle.isOnline ? '在线' : '离线'}
                    </span>
                  </div>
                  <div className="text-[10px] font-bold text-slate-400 truncate">
                    {vehicle.rentStatus || ''}
                    {vehicle.department ? ` · ${vehicle.department.replace('业务', '')}` : ''}
                    {vehicle.customer ? ` · ` : ''}
                    {vehicle.customer && <Blur>{vehicle.customer}</Blur>}
                  </div>
                </div>
              </div>
              <button onClick={onClose} className="p-2 -mr-1 text-slate-400 hover:text-slate-700 flex-shrink-0">
                <X size={18} />
              </button>
            </div>

            {/* 时间范围切换 */}
            <div className="px-4 pt-3">
              <div className="relative inline-flex bg-slate-100 p-0.5 rounded-lg">
                {RANGE_TABS.map(tab => (
                  <button
                    key={tab.key}
                    onClick={() => setRange(tab.key)}
                    className={`relative px-3 py-1 text-[10px] font-bold rounded-md transition-colors ${range === tab.key ? 'text-blue-600' : 'text-slate-500 hover:text-slate-700'}`}
                  >
                    {range === tab.key && (
                      <motion.div
                        layoutId="rangeTabBg"
                        className="absolute inset-0 bg-white shadow-sm rounded-md"
                        transition={{ type: 'spring', damping: 30, stiffness: 350 }}
                      />
                    )}
                    <span className="relative">{tab.label}</span>
                  </button>
                ))}
              </div>
            </div>

            {/* KPI cards */}
            <div className="px-4 py-3 grid grid-cols-3 gap-2">
              <div className="bg-slate-50 rounded-xl p-2.5">
                <div className="text-[9px] font-bold text-slate-400 uppercase">区间合计</div>
                <div className="text-base font-black text-slate-900 leading-tight">
                  {loading ? <span className="inline-block h-4 w-14 bg-slate-200 rounded animate-pulse align-middle" />
                    : <>{Math.round(stats.totalKm).toLocaleString()}<span className="text-[9px] font-bold text-slate-400 ml-0.5">km</span></>}
                </div>
              </div>
              <div className="bg-slate-50 rounded-xl p-2.5">
                <div className="text-[9px] font-bold text-slate-400 uppercase">日均</div>
                <div className="text-base font-black text-slate-900 leading-tight">
                  {loading ? <span className="inline-block h-4 w-10 bg-slate-200 rounded animate-pulse align-middle" />
                    : <>{Math.round(stats.avg).toLocaleString()}<span className="text-[9px] font-bold text-slate-400 ml-0.5">km</span></>}
                </div>
              </div>
              <div className="bg-slate-50 rounded-xl p-2.5">
                <div className="text-[9px] font-bold text-slate-400 uppercase">有数据天</div>
                <div className="text-base font-black text-slate-900 leading-tight">
                  {loading ? <span className="inline-block h-4 w-12 bg-slate-200 rounded animate-pulse align-middle" />
                    : <>{stats.synced}<span className="text-[9px] font-bold text-slate-400 ml-0.5">/{stats.totalDays}</span></>}
                </div>
              </div>
            </div>

            {/* Bar chart */}
            <div className="px-4 pb-2">
              <div className="flex items-center justify-between mb-1">
                <span className="text-[10px] font-bold text-slate-500">行驶里程</span>
                <span className="text-[9px] font-bold text-slate-300">单位 km</span>
              </div>
              <div className="bg-white rounded-xl border border-slate-50">
                <div className="h-[140px]">
                  {loading ? (
                    <SkeletonBars count={Math.min(skeletonCount, 30)} />
                  ) : (
                    <ResponsiveContainer width="100%" height="100%">
                      <BarChart data={historyDays} margin={{ top: 8, right: 8, bottom: 0, left: 0 }}>
                        <XAxis
                          dataKey="date"
                          tickFormatter={(d) => formatLabel(d, range)}
                          tick={{ fontSize: 9, fill: '#94a3b8' }}
                          tickLine={false}
                          axisLine={false}
                          interval="preserveStartEnd"
                          minTickGap={6}
                        />
                        <YAxis hide />
                        <Tooltip
                          formatter={(v) => [`${Math.round(Number(v) || 0).toLocaleString()} km`, '行驶里程']}
                          labelFormatter={(d) => `日期 ${d}`}
                          contentStyle={{ borderRadius: 12, fontSize: 11, padding: '4px 8px' }}
                          cursor={{ fill: 'rgba(59, 130, 246, 0.06)' }}
                        />
                        <Bar dataKey="dailyKm" radius={[3, 3, 0, 0]} animationDuration={500}>
                          {historyDays.map((d, i) => (
                            <Cell key={i} fill={d.isDataSynced ? '#3b82f6' : '#e2e8f0'} />
                          ))}
                        </Bar>
                      </BarChart>
                    </ResponsiveContainer>
                  )}
                </div>
              </div>
            </div>

            {/* 每日明细 */}
            <div className="flex-1 overflow-y-auto px-4 pb-4">
              <div className="text-[10px] font-bold text-slate-500 mb-1.5">每日明细</div>
              {loading ? (
                <SkeletonList count={Math.min(skeletonCount, 15)} />
              ) : (
                <motion.div
                  key={range}
                  initial={{ opacity: 0 }}
                  animate={{ opacity: 1 }}
                  transition={{ duration: 0.2 }}
                  className="space-y-1"
                >
                  {historyDays.slice().reverse().map((d, i) => (
                    <motion.div
                      key={d.date}
                      initial={{ opacity: 0, x: -8 }}
                      animate={{ opacity: 1, x: 0 }}
                      transition={{ delay: Math.min(i * 0.012, 0.4), duration: 0.18 }}
                      className="flex items-center justify-between py-1.5 px-2 rounded-lg hover:bg-slate-50"
                    >
                      <div className="w-[88px] flex-shrink-0">
                        <div className="text-[11px] font-mono font-bold text-slate-600">{d.date}</div>
                        <div
                          className={`text-[8px] font-bold ${
                            d.sourceCategory === 'INSTRUMENT'
                              ? 'text-violet-500'
                              : d.sourceCategory === 'GPS'
                                ? 'text-emerald-500'
                                : 'text-amber-500'
                          }`}
                          title={d.sourceProtocol || 'OneOS 当前未返回 sourceProtocol'}
                        >
                          {daySourceLabel(d)}
                        </div>
                      </div>
                      <div className="flex items-center gap-2 flex-1 ml-3">
                        <div className="flex-1 h-1.5 bg-slate-100 rounded-full overflow-hidden">
                          <motion.div
                            initial={{ width: 0 }}
                            animate={{ width: `${(d.dailyKm / stats.max) * 100}%` }}
                            transition={{ delay: Math.min(i * 0.012, 0.4) + 0.1, duration: 0.4 }}
                            className={`h-full rounded-full ${d.isDataSynced ? 'bg-blue-500' : 'bg-slate-200'}`}
                          />
                        </div>
                        <span className={`text-[11px] font-mono font-bold w-20 text-right ${d.isDataSynced ? 'text-slate-700' : 'text-amber-500/60'}`}>
                          {d.isDataSynced
                            ? <>{Math.round(d.dailyKm).toLocaleString()} <span className="text-[9px] text-slate-400">km</span></>
                            : <span className="text-[9px]">未对接</span>}
                        </span>
                      </div>
                    </motion.div>
                  ))}
                </motion.div>
              )}
            </div>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>
  );
}

function SkeletonBars({ count }: { count: number }) {
  return (
    <div className="flex items-end gap-1 h-full px-2 pb-2 pt-2">
      {Array.from({ length: count }).map((_, i) => (
        <div
          key={i}
          className="flex-1 bg-slate-100 rounded-t animate-pulse"
          style={{
            height: `${30 + Math.sin(i * 0.7) * 25 + Math.cos(i * 0.4) * 15 + 30}%`,
            animationDelay: `${i * 40}ms`,
          }}
        />
      ))}
    </div>
  );
}

function SkeletonList({ count }: { count: number }) {
  return (
    <div className="space-y-1">
      {Array.from({ length: count }).map((_, i) => (
        <div key={i} className="flex items-center justify-between py-1.5 px-2 animate-pulse" style={{ animationDelay: `${i * 30}ms` }}>
          <div className="h-3 w-20 bg-slate-100 rounded" />
          <div className="flex items-center gap-2 flex-1 ml-3">
            <div className="flex-1 h-1.5 bg-slate-100 rounded-full" />
            <div className="h-3 w-12 bg-slate-100 rounded" />
          </div>
        </div>
      ))}
    </div>
  );
}
