import type { FC, ReactNode } from 'react';
import { useEffect, useState, useMemo } from 'react';
import {
  Calendar,
  Users,
  DollarSign,
  ShoppingCart,
  Clock,
  Wallet,
  Sparkles,
  Activity,
  TrendingUp,
  ArrowRight,
} from 'lucide-react';
import {
  AreaChart,
  Area,
  BarChart,
  Bar,
  PieChart,
  Pie,
  Cell,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
} from 'recharts';
import Layout from '../components/Layout';
import {
  Card,
  Button,
  Badge,
  EmptyState,
  PageHeader,
  SkeletonStat,
  Skeleton,
  toast,
  badgeForAppointmentState,
} from '../components/ui';
import { odooApi, type DashboardStats, type Appointment, type Service, type ChartPoint } from '../services/odoo';

const formatCurrency = (value: number) =>
  new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN', maximumFractionDigits: 0 }).format(value);

interface StatCardProps {
  title: string;
  value: string | number;
  icon: ReactNode;
  trend?: string;
  loading?: boolean;
}

const StatCard: FC<StatCardProps> = ({ title, value, icon, trend, loading }) => {
  if (loading) return <SkeletonStat />;
  return (
    <Card className="hover:shadow-md transition">
      <Card.Body>
        <div className="flex items-center justify-between mb-3">
          <div className="w-10 h-10 rounded-xl bg-[#D9F99D]/50 flex items-center justify-center text-homenest-bark">
            {icon}
          </div>
          {trend && (
            <span className="text-xs font-medium text-homenest-bark bg-[#D9F99D] px-2 py-0.5 rounded-full">
              {trend}
            </span>
          )}
        </div>
        <p className="text-sm text-[#7A5C44] mb-1">{title}</p>
        <p className="text-2xl font-heading font-semibold text-homenest-bark">{value}</p>
      </Card.Body>
    </Card>
  );
};

const Dashboard: FC = () => {
  const [stats, setStats] = useState<DashboardStats | null>(null);
  const [chartData, setChartData] = useState<ChartPoint[]>([]);
  const [appointments, setAppointments] = useState<Appointment[]>([]);
  const [services, setServices] = useState<Service[]>([]);
  const [loadingStats, setLoadingStats] = useState(true);
  const [loadingChart, setLoadingChart] = useState(true);
  const [loadingAppointments, setLoadingAppointments] = useState(true);
  const [loadingServices, setLoadingServices] = useState(true);
  const [topServices, setTopServices] = useState<{ service: string; qty: number; revenue: number }[]>([]);
  const [aptReport, setAptReport] = useState<{ total: number; by_state: Record<string, number> } | null>(null);
  const [loadingExtras, setLoadingExtras] = useState(true);

  useEffect(() => {
    const loadStats = async () => {
      try {
        setLoadingStats(true);
        const res = await odooApi.getDashboard();
        if (res.status === 'success' && res.stats) {
          setStats(res.stats);
        }
      } catch (err) {
        toast.error('Error al cargar estadísticas del dashboard');
        console.error(err);
      } finally {
        setLoadingStats(false);
      }
    };

    const loadChart = async () => {
      try {
        setLoadingChart(true);
        const res = await odooApi.getWeeklyChart();
        if (res.status === 'success' && res.data) {
          setChartData(res.data);
        }
      } catch (err) {
        toast.error('Error al cargar gráfica semanal');
        console.error(err);
      } finally {
        setLoadingChart(false);
      }
    };

    const loadAppointments = async () => {
      try {
        setLoadingAppointments(true);
        const today = new Date().toISOString().split('T')[0];
        const res = await odooApi.getAppointments({ date: today, limit: '5' });
        if (res.status === 'success' && res.appointments) {
          setAppointments(res.appointments.slice(0, 5));
        }
      } catch (err) {
        toast.error('Error al cargar próximas citas');
        console.error(err);
      } finally {
        setLoadingAppointments(false);
      }
    };

    const loadServices = async () => {
      try {
        setLoadingServices(true);
        const res = await odooApi.getServices();
        if (res.status === 'success' && res.services) {
          setServices(res.services.slice(0, 6));
        }
      } catch (err) {
        toast.error('Error al cargar servicios');
        console.error(err);
      } finally {
        setLoadingServices(false);
      }
    };

    const loadExtras = async () => {
      try {
        setLoadingExtras(true);
        const start = new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString().split('T')[0];
        const end = new Date().toISOString().split('T')[0];
        const [topRes, aptRes] = await Promise.all([
          odooApi.getTopServices(start, end, 6),
          odooApi.getAppointmentsReport(start, end),
        ]);
        if (topRes.status === 'success') setTopServices(topRes.services || []);
        if (aptRes.status === 'success') setAptReport({ total: aptRes.total, by_state: aptRes.by_state });
      } catch (err) {
        console.error(err);
      } finally {
        setLoadingExtras(false);
      }
    };

    loadStats();
    loadChart();
    loadAppointments();
    loadServices();
    loadExtras();
  }, []);

  const statsConfig = useMemo(
    () => [
      {
        title: 'Citas Hoy',
        value: stats?.appointments_today ?? 0,
        icon: <Calendar size={20} />,
        trend: stats ? `${stats.appointments_month} este mes` : undefined,
      },
      {
        title: 'Pacientes',
        value: stats?.total_patients ?? 0,
        icon: <Users size={20} />,
        trend: stats ? `+${stats.new_patients_month} nuevos` : undefined,
      },
      {
        title: 'Ingresos Mes',
        value: stats ? formatCurrency(stats.revenue_month) : '$0',
        icon: <DollarSign size={20} />,
      },
      {
        title: 'Ventas Hoy',
        value: stats?.sales_today ?? 0,
        icon: <ShoppingCart size={20} />,
      },
      {
        title: 'Pendientes',
        value: stats?.pending_payments ?? 0,
        icon: <Clock size={20} />,
      },
      {
        title: 'Puntos Monedero',
        value: stats?.total_wallet_points ?? 0,
        icon: <Wallet size={20} />,
      },
    ],
    [stats]
  );

  const activityItems = useMemo(() => {
    return appointments.slice(0, 4).map((apt) => ({
      id: apt.id,
      title: `${apt.patient} — ${apt.service}`,
      subtitle: `${apt.date} ${apt.time}`,
      state: apt.state,
    }));
  }, [appointments]);

  const attendanceData = useMemo(() => {
    if (!aptReport) return [] as { name: string; value: number; color: string }[];
    const s = aptReport.by_state || {};
    const pick = (...keys: string[]) => keys.reduce((a, k) => a + (s[k] || 0), 0);
    return [
      { name: 'Completadas', value: pick('done'), color: '#D9F99D' },
      { name: 'Confirmadas', value: pick('confirmed', 'arrived', 'in_progress'), color: '#E9D5B7' },
      { name: 'Pendientes', value: pick('pending'), color: '#8B5E3C' },
      { name: 'No show', value: pick('no_show'), color: '#E57373' },
      { name: 'Canceladas', value: pick('cancelled'), color: '#E9D5B7' },
    ].filter((d) => d.value > 0);
  }, [aptReport]);

  const noShowRate = useMemo(() => {
    if (!aptReport || !aptReport.total) return 0;
    return Math.round(((aptReport.by_state?.no_show || 0) / aptReport.total) * 100);
  }, [aptReport]);

  return (
    <Layout title="Dashboard" subtitle="Panel de control de SKEEN Derma Experts">
      <PageHeader title="Dashboard" subtitle="Resumen general de la clínica">
        <Button variant="outline" size="sm">
          <Sparkles size={16} className="mr-2" />
          Bienvenido
        </Button>
      </PageHeader>

      {/* Hero / welcome */}
      <div className="bg-gradient-to-r from-[#8B5E3C] to-[#F3E2B3] rounded-2xl p-6 sm:p-8 text-white mb-6 sm:mb-8 shadow-sm">
        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
          <div>
            <h1 className="font-heading text-2xl sm:text-3xl mb-2">SKEEN Derma Experts</h1>
            <p className="text-white/90 text-sm sm:text-base max-w-xl">
              Ciencia, estética y cuidado personalizado en cada tratamiento. Gestiona tu clínica con confianza.
            </p>
          </div>
          <div className="shrink-0">
            <Button variant="secondary" size="sm" className="bg-homenest-cream-light/20 text-white border-white/30 hover:bg-homenest-cream-light/30">
              <TrendingUp size={16} className="mr-2" />
              Ver reportes
            </Button>
          </div>
        </div>
      </div>

      {/* Stats grid */}
      <div className="grid grid-cols-2 md:grid-cols-3 xl:grid-cols-6 gap-4 mb-6 sm:mb-8">
        {statsConfig.map((s) => (
          <StatCard
            key={s.title}
            title={s.title}
            value={s.value}
            icon={s.icon}
            trend={s.trend}
            loading={loadingStats}
          />
        ))}
      </div>

      {/* Chart + appointments */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6 mb-6 sm:mb-8">
        <Card>
          <Card.Header>
            <div>
              <h3 className="font-heading text-lg text-homenest-bark">Actividad semanal</h3>
              <p className="text-xs text-[#7A5C44]">Citas e ingresos de los últimos 7 días</p>
            </div>
          </Card.Header>
          <Card.Body>
            {loadingChart ? (
              <Skeleton count={8} className="h-6 w-full" />
            ) : chartData.length === 0 ? (
              <EmptyState title="Sin datos" subtitle="No hay información para la gráfica semanal." icon={<TrendingUp size={28} />} />
            ) : (
              <div className="h-[300px] w-full">
                <ResponsiveContainer width="100%" height={300}>
                  <AreaChart data={chartData} margin={{ top: 8, right: 8, left: -12, bottom: 0 }}>
                    <defs>
                      <linearGradient id="colorAppointments" x1="0" y1="0" x2="0" y2="1">
                        <stop offset="5%" stopColor="#8B5E3C" stopOpacity={0.3} />
                        <stop offset="95%" stopColor="#8B5E3C" stopOpacity={0} />
                      </linearGradient>
                      <linearGradient id="colorRevenue" x1="0" y1="0" x2="0" y2="1">
                        <stop offset="5%" stopColor="#D9F99D" stopOpacity={0.3} />
                        <stop offset="95%" stopColor="#D9F99D" stopOpacity={0} />
                      </linearGradient>
                    </defs>
                    <CartesianGrid strokeDasharray="3 3" stroke="#E9D5B7" />
                    <XAxis dataKey="name" tick={{ fontSize: 12, fill: '#7A5C44' }} axisLine={false} tickLine={false} />
                    <YAxis tick={{ fontSize: 12, fill: '#7A5C44' }} axisLine={false} tickLine={false} />
                    <Tooltip
                      contentStyle={{ borderRadius: 12, border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }}
                    />
                    <Area type="monotone" dataKey="appointments" stroke="#8B5E3C" fillOpacity={1} fill="url(#colorAppointments)" strokeWidth={2} />
                    <Area type="monotone" dataKey="revenue" stroke="#D9F99D" fillOpacity={1} fill="url(#colorRevenue)" strokeWidth={2} />
                  </AreaChart>
                </ResponsiveContainer>
              </div>
            )}
          </Card.Body>
        </Card>

        <Card className="flex flex-col">
          <Card.Header>
            <div>
              <h3 className="font-heading text-lg text-homenest-bark">Próximas citas</h3>
              <p className="text-xs text-[#7A5C44]">Citas programadas para hoy</p>
            </div>
            <Button variant="ghost" size="sm" className="hidden sm:inline-flex">
              Ver agenda
              <ArrowRight size={14} className="ml-1" />
            </Button>
          </Card.Header>
          <Card.Body className="flex-1">
            {loadingAppointments ? (
              <div className="space-y-3">
                {Array.from({ length: 4 }).map((_, i) => (
                  <Skeleton key={i} className="h-16 w-full" />
                ))}
              </div>
            ) : appointments.length === 0 ? (
              <EmptyState title="Sin citas" subtitle="No hay citas programadas para hoy." icon={<Calendar size={28} />} />
            ) : (
              <div className="space-y-3">
                {appointments.map((apt) => (
                  <div
                    key={apt.id}
                    className="flex items-center justify-between p-3 border border-[#E9D5B7] rounded-xl hover:bg-[#FEF3C7] transition"
                  >
                    <div className="min-w-0">
                      <p className="text-sm font-medium text-homenest-bark truncate">{apt.patient}</p>
                      <p className="text-xs text-[#7A5C44] truncate">{apt.service} • {apt.time}</p>
                    </div>
                    <Badge variant={badgeForAppointmentState(apt.state)}>{apt.state}</Badge>
                  </div>
                ))}
              </div>
            )}
          </Card.Body>
        </Card>
      </div>

      {/* Top servicios + Asistencia del mes */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6 mb-6 sm:mb-8">
        <Card>
          <Card.Header>
            <div>
              <h3 className="font-heading text-lg text-homenest-bark">Top servicios del mes</h3>
              <p className="text-xs text-[#7A5C44]">Por ingresos generados</p>
            </div>
          </Card.Header>
          <Card.Body>
            {loadingExtras ? (
              <Skeleton count={6} className="h-6 w-full" />
            ) : topServices.length === 0 ? (
              <EmptyState title="Sin datos" subtitle="No hay ventas en el mes." icon={<TrendingUp size={28} />} />
            ) : (
              <div className="h-[280px] w-full">
                <ResponsiveContainer width="100%" height={280}>
                  <BarChart data={topServices} layout="vertical" margin={{ top: 4, right: 16, left: 0, bottom: 4 }}>
                    <CartesianGrid strokeDasharray="3 3" horizontal={false} stroke="#E9D5B7" />
                    <XAxis type="number" tick={{ fontSize: 11, fill: '#7A5C44' }} axisLine={false} tickLine={false} tickFormatter={(v: number) => formatCurrency(v)} />
                    <YAxis
                      type="category"
                      dataKey="service"
                      width={150}
                      tick={{ fontSize: 11, fill: '#3E2C1C' }}
                      axisLine={false}
                      tickLine={false}
                      tickFormatter={(v: string) => (v.length > 22 ? `${v.slice(0, 22)}…` : v)}
                    />
                    <Tooltip
                      formatter={(v) => formatCurrency(Number(v))}
                      contentStyle={{ borderRadius: 12, border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }}
                    />
                    <Bar dataKey="revenue" fill="#8B5E3C" radius={[0, 4, 4, 0]} />
                  </BarChart>
                </ResponsiveContainer>
              </div>
            )}
          </Card.Body>
        </Card>

        <Card>
          <Card.Header>
            <div>
              <h3 className="font-heading text-lg text-homenest-bark">Asistencia del mes</h3>
              <p className="text-xs text-[#7A5C44]">
                {aptReport ? `${aptReport.total} citas · tasa no-show ${noShowRate}%` : 'Distribución por estado'}
              </p>
            </div>
          </Card.Header>
          <Card.Body>
            {loadingExtras ? (
              <Skeleton count={6} className="h-6 w-full" />
            ) : attendanceData.length === 0 ? (
              <EmptyState title="Sin datos" subtitle="No hay citas en el mes." icon={<Calendar size={28} />} />
            ) : (
              <div className="flex flex-col sm:flex-row items-center gap-4">
                <div className="h-[240px] w-full sm:w-1/2">
                  <ResponsiveContainer width="100%" height={240}>
                    <PieChart>
                      <Pie data={attendanceData} dataKey="value" nameKey="name" cx="50%" cy="50%" innerRadius={60} outerRadius={95} paddingAngle={2}>
                        {attendanceData.map((d, i) => (
                          <Cell key={`cell-${i}`} fill={d.color} />
                        ))}
                      </Pie>
                      <Tooltip contentStyle={{ borderRadius: 12, border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }} />
                    </PieChart>
                  </ResponsiveContainer>
                </div>
                <div className="flex-1 w-full space-y-2">
                  {attendanceData.map((d) => (
                    <div key={d.name} className="flex items-center justify-between text-sm">
                      <span className="flex items-center gap-2 text-[#7A5C44]">
                        <span className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: d.color }} />
                        {d.name}
                      </span>
                      <span className="font-medium text-homenest-bark">{d.value}</span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </Card.Body>
        </Card>
      </div>

      {/* Services + activity */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6">
        <Card>
          <Card.Header>
            <div>
              <h3 className="font-heading text-lg text-homenest-bark">Servicios destacados</h3>
              <p className="text-xs text-[#7A5C44]">Catálogo activo de tratamientos</p>
            </div>
          </Card.Header>
          <Card.Body>
            {loadingServices ? (
              <div className="space-y-3">
                {Array.from({ length: 4 }).map((_, i) => (
                  <Skeleton key={i} className="h-14 w-full" />
                ))}
              </div>
            ) : services.length === 0 ? (
              <EmptyState title="Sin servicios" subtitle="No hay servicios registrados." icon={<Sparkles size={28} />} />
            ) : (
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                {services.map((s) => (
                  <div
                    key={s.id}
                    className="flex items-center gap-3 p-3 border border-[#E9D5B7] rounded-xl hover:bg-[#FEF3C7] transition"
                  >
                    <div
                      className="w-10 h-10 rounded-lg shrink-0"
                      style={{ backgroundColor: s.color || '#78716c' }}
                    />
                    <div className="min-w-0">
                      <p className="text-sm font-medium text-homenest-bark truncate">{s.name}</p>
                      <p className="text-xs text-[#7A5C44]">${s.price} • {s.duration_min} min</p>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </Card.Body>
        </Card>

        <Card>
          <Card.Header>
            <div>
              <h3 className="font-heading text-lg text-homenest-bark">Actividad reciente</h3>
              <p className="text-xs text-[#7A5C44]">Últimos movimientos en la clínica</p>
            </div>
          </Card.Header>
          <Card.Body>
            {loadingAppointments ? (
              <div className="space-y-3">
                {Array.from({ length: 4 }).map((_, i) => (
                  <Skeleton key={i} className="h-14 w-full" />
                ))}
              </div>
            ) : activityItems.length === 0 ? (
              <EmptyState title="Sin actividad" subtitle="No hay movimientos recientes." icon={<Activity size={28} />} />
            ) : (
              <div className="space-y-3">
                {activityItems.map((item) => (
                  <div
                    key={item.id}
                    className="flex items-start gap-3 p-3 border border-[#E9D5B7] rounded-xl hover:bg-[#FEF3C7] transition"
                  >
                    <div className="w-9 h-9 rounded-full bg-[#F5EBD8] flex items-center justify-center text-[#7A5C44] shrink-0 mt-0.5">
                      <Activity size={16} />
                    </div>
                    <div className="min-w-0">
                      <p className="text-sm font-medium text-homenest-bark truncate">{item.title}</p>
                      <p className="text-xs text-[#7A5C44]">{item.subtitle}</p>
                    </div>
                    <Badge variant={badgeForAppointmentState(item.state)} className="shrink-0">
                      {item.state}
                    </Badge>
                  </div>
                ))}
              </div>
            )}
          </Card.Body>
        </Card>
      </div>
    </Layout>
  );
};

export default Dashboard;
