import type { FC } from 'react';
import { useEffect, useState, useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Search, Plus, Minus, Wallet } from 'lucide-react';
import Layout from '../components/Layout';
import {
  Card,
  Button,
  Input,
  TextArea,
  Modal,
  EmptyState,
  PageHeader,
  Skeleton,
  MobileCard,
  toast,
} from '../components/ui';
import { odooApi, type Wallet as WalletType, type MonederoPuntosReport } from '../services/odoo';

type TxType = 'accrual' | 'redemption';

const TABS = [
  { key: 'cuentas', label: 'Cuentas' },
  { key: 'reporte', label: 'Reporte de puntos' },
] as const;

const txTypeLabels: Record<string, string> = {
  accrual: 'Acumulación', redemption: 'Redención', adjustment: 'Ajuste', expiration: 'Vencimiento',
};

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

const fmtMoney = (n: number) =>
  (n || 0).toLocaleString('es-MX', { style: 'currency', currency: 'MXN', maximumFractionDigits: 0 });

const Monedero: FC = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const tab = searchParams.get('tab') || 'cuentas';
  const setTab = (t: string) => setSearchParams({ tab: t });
  const [wallets, setWallets] = useState<WalletType[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [search, setSearch] = useState('');
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(0);
  const [modalOpen, setModalOpen] = useState(false);
  const [selected, setSelected] = useState<WalletType | null>(null);
  const [txType, setTxType] = useState<TxType>('accrual');
  const [points, setPoints] = useState('');
  const [description, setDescription] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [reporte, setReporte] = useState<MonederoPuntosReport | null>(null);
  const [reporteLoading, setReporteLoading] = useState(false);
  const [repStart, setRepStart] = useState(inicioDeMes());
  const [repEnd, setRepEnd] = useState(() => new Date().toISOString().split('T')[0]);

  const load = useCallback(async () => {
    if (tab !== 'cuentas') return;
    try {
      setLoading(true);
      setError(null);
      const res = await odooApi.getWallets({ search, page, page_size: pageSize });
      if (res.status === 'success') {
        setWallets(res.wallets);
        setTotal(res.total ?? 0);
        setTotalPages(res.total_pages ?? 0);
      }
    } catch (err) {
      setError('Error al cargar monederos');
      toast.error('Error al cargar monederos');
      console.error(err);
    } finally {
      setLoading(false);
    }
  }, [search, page, pageSize, tab]);

  const loadReporte = useCallback(async () => {
    if (tab !== 'reporte') return;
    try {
      setReporteLoading(true);
      const res = await odooApi.getMonederoPuntos(repStart || undefined, repEnd || undefined);
      if (res.status === 'success') {
        const { by_type, puntos_activos, cuentas, equivalente_mxn } = res;
        setReporte({ by_type, puntos_activos, cuentas, equivalente_mxn });
      }
    } catch (err) {
      toast.error('Error al cargar reporte de puntos');
      console.error(err);
    } finally {
      setReporteLoading(false);
    }
  }, [tab, repStart, repEnd]);

  useEffect(() => {
    setPage(1);
  }, [search]);

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

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

  const openModal = (w: WalletType, type: TxType) => {
    setSelected(w);
    setTxType(type);
    setPoints('');
    setDescription('');
    setModalOpen(true);
  };

  const submit = async () => {
    if (!selected) return;
    const value = parseFloat(points);
    if (Number.isNaN(value) || value <= 0) {
      toast.error('Ingresa una cantidad válida de puntos');
      return;
    }
    if (txType === 'redemption' && value > selected.points) {
      toast.error('No puede redimir más puntos de los disponibles');
      return;
    }
    try {
      setSubmitting(true);
      await odooApi.walletTransaction({
        phone: selected.phone,
        type: txType,
        points: value,
        description,
      });
      toast.success(txType === 'accrual' ? 'Puntos acumulados' : 'Puntos redimidos');
      setModalOpen(false);
      await load();
    } catch (err) {
      toast.error('Error en transacción');
      console.error(err);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Layout title="Monedero" subtitle="Puntos y recompensas">
      <PageHeader title="Monedero" subtitle="Busca por teléfono y gestiona puntos" />

      {/* Tabs */}
      <div className="flex flex-wrap gap-1.5 mb-4">
        {TABS.map((t) => (
          <button
            key={t.key}
            type="button"
            onClick={() => setTab(t.key)}
            className={`px-4 py-2 text-sm font-medium rounded-full transition ${
              tab === t.key ? 'bg-theme-accent text-theme-inverse' : 'bg-theme-accent-bg text-theme-heading hover:bg-theme-bg'
            }`}
          >
            {t.label}
          </button>
        ))}
      </div>

      {tab === 'reporte' ? (
        <>
          <Card className="mb-4">
            <Card.Body>
              <div className="flex flex-col sm:flex-row gap-3">
                <Input label="Inicio" type="date" value={repStart} onChange={(e) => setRepStart(e.target.value)} className="sm:max-w-[160px]" />
                <Input label="Fin" type="date" value={repEnd} onChange={(e) => setRepEnd(e.target.value)} className="sm:max-w-[160px]" />
              </div>
            </Card.Body>
          </Card>

          {reporteLoading ? (
            <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
              {Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className="h-24 w-full" />)}
            </div>
          ) : reporte ? (
            <>
              <div className="grid grid-cols-2 md:grid-cols-3 gap-4 mb-4">
                <Card className="p-4 bg-theme-bg border-0">
                  <p className="text-xs text-theme-muted">Puntos activos</p>
                  <p className="text-xl font-heading font-semibold text-theme-heading">{reporte.puntos_activos} pts</p>
                </Card>
                <Card className="p-4 bg-theme-bg border-0">
                  <p className="text-xs text-theme-muted">Equivalente</p>
                  <p className="text-xl font-heading font-semibold text-theme-heading">{fmtMoney(reporte.equivalente_mxn)}</p>
                </Card>
                <Card className="p-4 bg-theme-bg border-0">
                  <p className="text-xs text-theme-muted">Cuentas con monedero</p>
                  <p className="text-xl font-heading font-semibold text-theme-heading">{reporte.cuentas}</p>
                </Card>
              </div>
              <Card>
                <Card.Body>
                  <h3 className="font-heading text-xl text-theme-heading mb-1">Movimientos del periodo</h3>
                  <p className="text-xs text-theme-muted mb-4">1 punto = $1 MXN (conversión fija del sistema).</p>
                  {Object.keys(reporte.by_type).length === 0 ? (
                    <p className="text-sm text-theme-muted">Sin movimientos en el periodo.</p>
                  ) : (
                    <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
                      {Object.entries(reporte.by_type).map(([type, points]) => (
                        <div key={type} className="p-3 bg-theme-bg rounded-xl">
                          <p className="text-xs text-theme-muted">{txTypeLabels[type] || type}</p>
                          <p className={`text-lg font-semibold ${type === 'redemption' || type === 'expiration' ? 'text-rose-600' : 'text-theme-heading'}`}>
                            {points > 0 && type !== 'redemption' && type !== 'expiration' ? '+' : ''}{points} pts
                          </p>
                        </div>
                      ))}
                    </div>
                  )}
                </Card.Body>
              </Card>
            </>
          ) : null}
        </>
      ) : (
      <>
      <Card>
        <Card.Body>
          <div className="flex flex-col sm:flex-row sm:items-center gap-3 mb-4 sm:mb-6">
            <div className="relative w-full sm:max-w-sm">
              <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-theme-muted" />
              <Input
                placeholder="Buscar por teléfono..."
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                className="pl-10"
              />
            </div>
          </div>

          {error && <p className="text-rose-600 text-sm mb-4">{error}</p>}

          {loading ? (
            <Skeleton count={5} className="h-14 w-full" />
          ) : wallets.length === 0 ? (
            <EmptyState title="Sin monederos" subtitle="No se encontraron monederos." icon={<Wallet size={28} />} />
          ) : (
            <>
              <div className="hidden sm:block overflow-x-auto">
                <table className="w-full">
                  <thead className="bg-theme-bg">
                    <tr>
                      <th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Paciente</th>
                      <th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Teléfono</th>
                      <th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Puntos</th>
                      <th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Equivalente MXN</th>
                      <th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Acciones</th>
                    </tr>
                  </thead>
                  <tbody className="divide-y">
                    {wallets.map((w) => (
                      <tr key={w.id} className="hover:bg-theme-bg">
                        <td className="p-3 text-sm font-medium text-theme-heading">{w.patient}</td>
                        <td className="p-3 text-sm text-theme-muted">{w.phone}</td>
                        <td className="p-3 text-sm font-medium text-theme-heading">{w.points} pts</td>
                        <td className="p-3 text-sm text-theme-muted">${w.equivalent_mxn}</td>
                        <td className="p-3">
                          <div className="flex items-center gap-1">
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => openModal(w, 'accrual')}
                              title="Acumular"
                            >
                              <Plus size={16} className="text-theme-heading" />
                            </Button>
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => openModal(w, 'redemption')}
                              title="Redimir"
                              disabled={w.points <= 0}
                            >
                              <Minus size={16} className="text-rose-600" />
                            </Button>
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <div className="sm:hidden space-y-3">
                {wallets.map((w) => (
                  <MobileCard
                    key={w.id}
                    title={w.patient}
                    subtitle={w.phone}
                    rows={[
                      { label: 'Puntos', value: `${w.points} pts` },
                      { label: 'Equivalente', value: `$${w.equivalent_mxn}` },
                    ]}
                    actions={
                      <>
                        <Button variant="ghost" size="sm" onClick={() => openModal(w, 'accrual')}>
                          <Plus size={16} className="text-theme-heading" />
                        </Button>
                        <Button variant="ghost" size="sm" onClick={() => openModal(w, 'redemption')} disabled={w.points <= 0}>
                          <Minus size={16} className="text-rose-600" />
                        </Button>
                      </>
                    }
                  />
                ))}
              </div>

              {/* Paginación */}
              <div className="flex flex-col sm:flex-row items-center justify-between gap-3 mt-4 pt-4 border-t border-theme-border">
                <p className="text-sm text-theme-muted">
                  {total} monederos · página {page} de {totalPages || 1}
                </p>
                <div className="flex items-center gap-2">
                  <select
                    value={pageSize}
                    onChange={(e) => { setPageSize(parseInt(e.target.value, 10)); setPage(1); }}
                    className="border border-theme-border-strong rounded-lg px-2 py-1.5 text-sm"
                  >
                    <option value={25}>25</option>
                    <option value={50}>50</option>
                    <option value={100}>100</option>
                    <option value={200}>200</option>
                  </select>
                  <Button variant="outline" size="sm" disabled={page <= 1} onClick={() => setPage((p) => Math.max(1, p - 1))}>
                    Anterior
                  </Button>
                  <Button variant="outline" size="sm" disabled={page >= totalPages} onClick={() => setPage((p) => p + 1)}>
                    Siguiente
                  </Button>
                </div>
              </div>
            </>
          )}
        </Card.Body>
      </Card>

      <Modal
        isOpen={modalOpen}
        onClose={() => setModalOpen(false)}
        title={txType === 'accrual' ? 'Acumular puntos' : 'Redimir puntos'}
        maxWidth="sm"
        footer={
          <>
            <Button variant="outline" onClick={() => setModalOpen(false)}>Cancelar</Button>
            <Button onClick={submit} loading={submitting}>Guardar</Button>
          </>
        }
      >
        {selected && (
          <div className="space-y-4">
            <p className="text-sm text-theme-muted">
              Paciente: <span className="font-medium text-theme-heading">{selected.patient}</span>
            </p>
            <p className="text-sm text-theme-muted">
              Puntos disponibles: <span className="font-medium text-theme-heading">{selected.points} pts</span>
            </p>
            <Input
              label="Puntos *"
              type="number"
              min={1}
              value={points}
              onChange={(e) => setPoints(e.target.value)}
            />
            <TextArea
              label="Descripción"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
            />
          </div>
        )}
      </Modal>
      </>
      )}
    </Layout>
  );
};

export default Monedero;
