import type { FC } from 'react';
import { useEffect, useState, useCallback } from 'react';
import { LayoutGrid } from 'lucide-react';
import { Card, Input, Badge, Skeleton, toast } from '../ui';
import { ExportButton } from '../ui/ExportButton';
import { exportToExcel } from '../../lib/exporter';
import { odooApi, type ConcentradoReport as ConcentradoData } from '../../services/odoo';
import type { BadgeVariant } from '../ui/Badge';

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

const citaStateLabels: Record<string, string> = {
  pending: 'Pendiente', confirmed: 'Confirmada', arrived: 'Llegó',
  in_progress: 'En curso', done: 'Completada', cancelled: 'Cancelada', no_show: 'No show',
};
const visitaStateLabels: Record<string, string> = {
  en_curso: 'En curso', completada: 'Completada', cancelada: 'Cancelada',
};
const metodoLabels: Record<string, string> = {
  cash: 'Efectivo', card: 'Tarjeta', transfer: 'Transferencia',
  stripe: 'Stripe', mercadopago: 'MercadoPago',
};
const stateBadge = (state: string): BadgeVariant =>
  state === 'done' || state === 'completada' ? 'success'
    : state === 'cancelled' || state === 'no_show' || state === 'cancelada' ? 'danger'
    : state === 'pending' || state === 'en_curso' ? 'warning' : 'info';

const inicioDeMes = () => {
  const d = new Date();
  d.setDate(1);
  return d.toISOString().split('T')[0];
};
const hoy = () => new Date().toISOString().split('T')[0];

const Kpi: FC<{ label: string; value: React.ReactNode; rose?: boolean }> = ({ label, value, rose }) => (
  <Card className="p-4 bg-theme-bg border-0">
    <p className="text-xs text-theme-muted">{label}</p>
    <p className={`text-xl font-heading font-semibold ${rose ? 'text-rose-600' : 'text-theme-heading'}`}>{value}</p>
  </Card>
);

const ConcentradoReport: FC = () => {
  const [start, setStart] = useState(inicioDeMes());
  const [end, setEnd] = useState(hoy());
  const [data, setData] = useState<ConcentradoData | null>(null);
  const [loading, setLoading] = useState(true);

  const load = useCallback(async () => {
    try {
      setLoading(true);
      const res = await odooApi.getConcentrado(start, end);
      if (res.status === 'success') {
        const { citas, ventas, pagos, devoluciones, pacientes_nuevos, visitas, start: s, end: e } = res;
        setData({ citas, ventas, pagos, devoluciones, pacientes_nuevos, visitas, start: s, end: e });
      }
    } catch (err) {
      toast.error('Error al cargar concentrado');
      console.error(err);
    } finally {
      setLoading(false);
    }
  }, [start, end]);

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

  const [exporting, setExporting] = useState(false);
  const exportar = async () => {
    if (!data) return;
    try {
      setExporting(true);
      const rows: Record<string, unknown>[] = [
        { seccion: 'Citas', concepto: 'Total', cantidad: data.citas.total, monto: null },
        ...Object.entries(data.citas.by_state).map(([k, v]) => ({ seccion: 'Citas', concepto: citaStateLabels[k] || k, cantidad: v, monto: null })),
        { seccion: 'Visitas', concepto: 'Total', cantidad: data.visitas.total, monto: null },
        ...Object.entries(data.visitas.by_state).map(([k, v]) => ({ seccion: 'Visitas', concepto: visitaStateLabels[k] || k, cantidad: v, monto: null })),
        { seccion: 'Ventas', concepto: 'Cantidad', cantidad: data.ventas.count, monto: null },
        { seccion: 'Ventas', concepto: 'Total vendido', cantidad: null, monto: data.ventas.total },
        { seccion: 'Ventas', concepto: 'Por cobrar', cantidad: null, monto: data.ventas.total_due },
        { seccion: 'Cobros', concepto: 'Total cobrado', cantidad: data.pagos.count, monto: data.pagos.total },
        ...Object.entries(data.pagos.by_method).map(([k, v]) => ({ seccion: 'Cobros', concepto: metodoLabels[k] || k, cantidad: null, monto: v })),
        { seccion: 'Devoluciones', concepto: 'Devuelto', cantidad: data.devoluciones.count, monto: data.devoluciones.total },
        { seccion: 'Pacientes', concepto: 'Nuevos en el periodo', cantidad: data.pacientes_nuevos, monto: null },
      ];
      await exportToExcel({
        filename: `concentrado-${start}_${end}`,
        sheetName: 'Concentrado',
        title: 'Concentrado del periodo',
        subtitle: `Del ${start} al ${end}`,
        columns: [
          { header: 'Sección', key: 'seccion' },
          { header: 'Concepto', key: 'concepto' },
          { header: 'Cantidad', key: 'cantidad', format: 'number' },
          { header: 'Monto', key: 'monto', format: 'currency' },
        ],
        rows,
      });
      toast.success('Excel descargado');
    } catch (err) {
      toast.error('Error al exportar');
      console.error(err);
    } finally {
      setExporting(false);
    }
  };

  return (
    <div className="space-y-4 sm:space-y-6">
      <Card>
        <Card.Body>
          <div className="flex flex-col sm:flex-row gap-3 items-end">
            <Input label="Inicio" type="date" value={start} onChange={(e) => setStart(e.target.value)} className="sm:max-w-[160px]" />
            <Input label="Fin" type="date" value={end} onChange={(e) => setEnd(e.target.value)} className="sm:max-w-[160px]" />
            <div className="sm:ml-auto">
              <ExportButton onClick={exportar} loading={exporting} />
            </div>
          </div>
        </Card.Body>
      </Card>

      {loading ? (
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
          {Array.from({ length: 8 }).map((_, i) => <Skeleton key={i} className="h-24 w-full" />)}
        </div>
      ) : data ? (
        <>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <Kpi label="Citas" value={data.citas.total} />
            <Kpi label="Visitas clínicas" value={data.visitas.total} />
            <Kpi label="Pacientes nuevos" value={data.pacientes_nuevos} />
            <Kpi label="Ventas" value={data.ventas.count} />
            <Kpi label="Total vendido" value={formatCurrency(data.ventas.total)} />
            <Kpi label="Cobrado" value={formatCurrency(data.pagos.total)} />
            <Kpi label="Por cobrar" value={formatCurrency(data.ventas.total_due)} rose={data.ventas.total_due > 0} />
            <Kpi label="Devoluciones" value={`${data.devoluciones.count} · ${formatCurrency(data.devoluciones.total)}`} rose={data.devoluciones.total > 0} />
          </div>

          <div className="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6">
            <Card>
              <Card.Body>
                <h3 className="font-heading text-lg text-theme-heading mb-3 flex items-center">
                  <LayoutGrid size={18} className="mr-2" /> Citas por estado
                </h3>
                <div className="flex flex-wrap gap-2">
                  {Object.entries(data.citas.by_state).map(([state, count]) => (
                    <Badge key={state} variant={stateBadge(state)}>
                      {citaStateLabels[state] || state}: {count}
                    </Badge>
                  ))}
                  {data.citas.total === 0 && <p className="text-sm text-theme-muted">Sin citas.</p>}
                </div>
              </Card.Body>
            </Card>
            <Card>
              <Card.Body>
                <h3 className="font-heading text-lg text-theme-heading mb-3">Cobros por método</h3>
                {Object.keys(data.pagos.by_method).length === 0 ? (
                  <p className="text-sm text-theme-muted">Sin cobros.</p>
                ) : (
                  <div className="space-y-2">
                    {Object.entries(data.pagos.by_method).map(([method, amount]) => (
                      <div key={method} className="flex items-center justify-between p-2.5 bg-theme-bg rounded-lg text-sm">
                        <span className="text-theme-heading">{metodoLabels[method] || method}</span>
                        <span className="font-medium text-theme-heading">{formatCurrency(amount)}</span>
                      </div>
                    ))}
                  </div>
                )}
              </Card.Body>
            </Card>
            <Card>
              <Card.Body>
                <h3 className="font-heading text-lg text-theme-heading mb-3">Visitas por estado</h3>
                <div className="flex flex-wrap gap-2">
                  {Object.entries(data.visitas.by_state).map(([state, count]) => (
                    <Badge key={state} variant={stateBadge(state)}>
                      {visitaStateLabels[state] || state}: {count}
                    </Badge>
                  ))}
                  {data.visitas.total === 0 && <p className="text-sm text-theme-muted">Sin visitas.</p>}
                </div>
              </Card.Body>
            </Card>
          </div>
        </>
      ) : null}
    </div>
  );
};

export default ConcentradoReport;
