import { useEffect, useMemo, useState } from 'react';
import { AlertTriangle, CheckCircle2, Clock, Megaphone, RefreshCw, RotateCcw, Send, Users, XCircle } from 'lucide-react';
import RefreshStatus from '../components/RefreshStatus';
import type { CampaignGroup, CampaignPreview, CampaignProcessSummary, CampaignQueueSummary, CampaignStatus } from '../types';
import { fetchCampaignPreview, fetchCampaigns, processCampaignsNow, retryCampaignGroup } from '../dataService';

const statusLabels: Record<CampaignStatus, string> = {
  pending: 'Pendente',
  processing: 'Processando',
  sent: 'Enviada',
  failed: 'Falhou',
  skipped: 'Ignorada'
};

type StatusVisual = {
  accent: string;
  bg: string;
  border: string;
  text: string;
};

type PreviewFilter = 'all' | 'ready' | 'near' | 'below';

const statusStyles: Record<CampaignStatus, StatusVisual> = {
  pending: { accent: '#FFC247', bg: 'rgba(255, 194, 71, 0.10)', border: 'rgba(255, 194, 71, 0.28)', text: '#FFC247' },
  processing: { accent: '#25C2FF', bg: 'rgba(37, 194, 255, 0.10)', border: 'rgba(37, 194, 255, 0.28)', text: '#25C2FF' },
  sent: { accent: '#52DFA0', bg: 'rgba(82, 223, 160, 0.10)', border: 'rgba(82, 223, 160, 0.28)', text: '#52DFA0' },
  failed: { accent: '#FF7A9B', bg: 'rgba(255, 122, 155, 0.11)', border: 'rgba(255, 122, 155, 0.32)', text: '#FF7A9B' },
  skipped: { accent: '#8c9298', bg: 'rgba(140, 146, 152, 0.08)', border: 'rgba(140, 146, 152, 0.24)', text: '#b3b7bb' }
};

const statusIcons: Record<CampaignStatus, typeof Clock> = {
  pending: Clock,
  processing: RefreshCw,
  sent: CheckCircle2,
  failed: XCircle,
  skipped: AlertTriangle
};

const formatDate = (value?: string | null) => {
  if (!value) return '-';
  return new Date(value).toLocaleString('pt-BR');
};

const formatDelta = (value: number) => `${value} un.`;

const NEAR_THRESHOLD_PERCENT = 80;

const statusPillStyle = (status: CampaignStatus) => {
  const style = statusStyles[status];
  return {
    backgroundColor: style.bg,
    borderColor: style.border,
    color: style.text
  };
};

const CampaignsSkeleton = () => (
  <div className="space-y-6" aria-label="Carregando campanhas">
    <div className="grid grid-cols-1 md:grid-cols-5 gap-4">
      {[0, 1, 2, 3, 4].map(item => (
        <div key={`campaign-kpi-skeleton-${item}`} className="bg-dark-card border border-dark-border rounded-2xl p-4">
          <div className="flex items-center justify-between">
            <div className="skeleton h-3 w-24" />
            <div className="skeleton h-4 w-4 rounded-full" />
          </div>
          <div className="skeleton mt-4 h-7 w-12" />
        </div>
      ))}
    </div>

    <div className="grid grid-cols-1 xl:grid-cols-2 gap-6">
      {[0, 1].map(section => (
        <div key={`campaign-card-skeleton-${section}`} className="bg-dark-card border border-dark-border rounded-2xl p-6">
          <div className="skeleton h-5 w-48" />
          <div className="mt-5 space-y-3">
            {[0, 1, 2, 3].map(item => (
              <div key={`campaign-card-row-skeleton-${section}-${item}`} className="rounded-xl border border-dark-border p-3">
                <div className="skeleton h-4 w-3/5" />
                <div className="mt-3 skeleton h-2 w-full" />
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>

    <div className="bg-dark-card border border-dark-border rounded-2xl overflow-hidden">
      <div className="border-b border-dark-border p-4">
        <div className="grid grid-cols-[1.5fr_130px_90px_80px_90px_150px_110px] gap-5">
          {[0, 1, 2, 3, 4, 5, 6].map(item => (
            <div key={`campaign-table-head-skeleton-${item}`} className="skeleton h-3" />
          ))}
        </div>
      </div>
      <div className="p-6 space-y-5">
        {[0, 1, 2, 3, 4, 5].map(row => (
          <div key={`campaign-table-row-skeleton-${row}`} className="grid grid-cols-[1.5fr_130px_90px_80px_90px_150px_110px] gap-5">
            {[0, 1, 2, 3, 4, 5, 6].map(column => (
              <div key={`campaign-table-cell-skeleton-${row}-${column}`} className="skeleton h-4" />
            ))}
          </div>
        ))}
      </div>
    </div>
  </div>
);

const Campaigns = () => {
  const [summary, setSummary] = useState<CampaignQueueSummary | null>(null);
  const [preview, setPreview] = useState<CampaignPreview | null>(null);
  const [processResult, setProcessResult] = useState<CampaignProcessSummary | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [isProcessing, setIsProcessing] = useState(false);
  const [previewFilter, setPreviewFilter] = useState<PreviewFilter>('all');

  const loadCampaigns = async () => {
    setIsLoading(true);
    const [campaignsData, previewData] = await Promise.all([
      fetchCampaigns(),
      fetchCampaignPreview()
    ]);
    setSummary(campaignsData);
    setPreview(previewData);
    setIsLoading(false);
  };

  useEffect(() => {
    // Campaign state is loaded from the backend after the protected route mounts.
    // eslint-disable-next-line react-hooks/set-state-in-effect
    void loadCampaigns();
  }, []);

  const groupedCounts = useMemo(() => {
    const counts: Record<CampaignStatus, number> = {
      pending: 0,
      processing: 0,
      sent: 0,
      failed: 0,
      skipped: 0
    };
    summary?.groups.forEach(group => {
      counts[group.status] += 1;
    });
    return counts;
  }, [summary]);

  const threshold = summary?.threshold ?? preview?.threshold ?? 100;
  const previewProducts = useMemo(() => {
    const ready = (preview?.readyProducts || []).map(product => ({ ...product, isReady: true }));
    const below = (preview?.belowThresholdProducts || []).map(product => ({ ...product, isReady: false }));
    return [...ready, ...below].sort((a, b) => Number(b.isReady) - Number(a.isReady) || b.total_delta - a.total_delta);
  }, [preview]);

  const previewProductRows = useMemo(() => {
    return previewProducts.map(product => {
      const progress = threshold ? Math.min(100, (product.total_delta / threshold) * 100) : 0;
      return {
        ...product,
        progress,
        isNear: !product.isReady && progress >= NEAR_THRESHOLD_PERCENT
      };
    });
  }, [previewProducts, threshold]);

  const filteredPreviewProducts = useMemo(() => {
    switch (previewFilter) {
      case 'ready':
        return previewProductRows.filter(product => product.isReady);
      case 'near':
        return previewProductRows.filter(product => product.isNear);
      case 'below':
        return previewProductRows.filter(product => !product.isReady);
      default:
        return previewProductRows;
    }
  }, [previewFilter, previewProductRows]);

  const previewFilterOptions = useMemo(() => [
    { key: 'all' as const, label: 'Todos', count: previewProductRows.length },
    { key: 'ready' as const, label: 'Prontos', count: previewProductRows.filter(product => product.isReady).length },
    { key: 'near' as const, label: 'Quase prontos', count: previewProductRows.filter(product => product.isNear).length },
    { key: 'below' as const, label: 'Abaixo', count: previewProductRows.filter(product => !product.isReady).length }
  ], [previewProductRows]);

  const resultStats = processResult ? [
    { label: 'Processados', value: processResult.claimed, color: '#25C2FF' },
    { label: 'Enviados', value: processResult.sentGroups, color: '#52DFA0' },
    { label: 'Falhas', value: processResult.failedGroups, color: '#FF7A9B' },
    { label: 'Abaixo do limite', value: processResult.pendingBelowThresholdGroups, color: '#FFC247' }
  ] : [];

  const statusSummary = (Object.keys(statusLabels) as CampaignStatus[]).map(status => ({
    status,
    label: statusLabels[status],
    count: groupedCounts[status],
    Icon: statusIcons[status],
    style: statusStyles[status]
  }));

  const shouldShowSkeleton = isLoading && !summary && !preview;
  const isRefreshing = isLoading && Boolean(summary || preview);

  const handleProcessNow = async () => {
    setIsProcessing(true);
    const result = await processCampaignsNow();
    setProcessResult(result);
    await loadCampaigns();
    setIsProcessing(false);
  };

  const handleRetry = async (group: CampaignGroup) => {
    setIsProcessing(true);
    await retryCampaignGroup(group.baseProductName);
    await loadCampaigns();
    setIsProcessing(false);
  };

  return (
    <div className="space-y-6">
      <div className="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold mb-2 text-dark-text">Campanhas</h1>
          <p className="text-dark-muted font-medium">Fila de reposição, prévia de envio e histórico das campanhas do WhatsApp.</p>
        </div>
        <div className="flex flex-wrap gap-3">
          <button
            onClick={() => void loadCampaigns()}
            disabled={isLoading || isProcessing}
            className="inline-flex items-center gap-2 bg-dark-card border border-dark-border px-4 py-2.5 rounded-xl hover:border-brand-primary transition-colors text-sm font-medium text-dark-text disabled:opacity-50 cursor-pointer"
          >
            <RefreshCw size={16} className={isLoading ? 'animate-spin' : ''} />
            Atualizar
          </button>
          <button
            onClick={handleProcessNow}
            disabled={isProcessing || !preview?.readyProducts.length}
            className="inline-flex items-center gap-2 bg-brand-primary text-brand-contrast px-4 py-2.5 rounded-xl hover:opacity-90 transition-opacity text-sm font-bold disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
          >
            <Send size={16} />
            Processar agora
          </button>
        </div>
      </div>

      <RefreshStatus isRefreshing={isRefreshing || isProcessing} label={isProcessing ? 'Processando campanhas' : 'Atualizando campanhas'} />

      {processResult && (
        <div className="bg-dark-card border border-dark-border rounded-2xl p-3">
          <div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
            {resultStats.map(item => (
              <div key={item.label} className="flex items-center justify-between gap-3 rounded-xl bg-dark-input/55 px-3 py-2">
                <span className="flex items-center gap-2 text-xs font-bold uppercase tracking-wide text-dark-muted">
                  <span className="h-2 w-2 rounded-full" style={{ backgroundColor: item.color }} />
                  {item.label}
                </span>
                <span className="text-sm font-bold text-dark-text">{item.value}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {shouldShowSkeleton ? (
        <CampaignsSkeleton />
      ) : (
        <div className={isRefreshing || isProcessing ? 'refreshing-content space-y-6' : 'space-y-6'} aria-busy={isRefreshing || isProcessing}>
      <div className="grid grid-cols-1 md:grid-cols-5 gap-4">
        {statusSummary.map(({ status, label, count, Icon, style }) => {
          return (
            <div key={status} className="bg-dark-card border border-dark-border rounded-2xl p-4">
              <div className="flex items-center justify-between mb-3">
                <span className="text-xs font-bold uppercase tracking-widest text-dark-muted">{label}</span>
                <Icon className="w-4 h-4" style={{ color: style.accent }} />
              </div>
              <p className="text-2xl font-bold text-dark-text">{count}</p>
            </div>
          );
        })}
      </div>

      <div className="grid grid-cols-1 xl:grid-cols-2 gap-6">
        <div className="bg-dark-card border border-dark-border rounded-2xl p-6">
          <div className="flex items-center gap-2 mb-4">
            <Megaphone className="w-5 h-5 text-brand-primary" />
            <h2 className="text-lg font-bold text-dark-text">Prévia do próximo envio</h2>
          </div>
          <div className="space-y-4">
            <div>
              <p className="text-xs font-bold text-dark-muted uppercase tracking-widest mb-1">Produtos prontos</p>
              <p className="text-dark-text font-semibold">{preview?.productsText || 'Nenhum produto atingiu o limite ainda.'}</p>
            </div>
            <div className="grid grid-cols-2 gap-3">
              <div className="bg-dark-input rounded-xl p-3 border border-dark-border">
                <p className="text-xs text-dark-muted mb-1">Clientes alvo</p>
                <p className="text-xl font-bold text-dark-text">{preview?.customerCount ?? 0}</p>
              </div>
              <div className="bg-dark-input rounded-xl p-3 border border-dark-border">
                <p className="text-xs text-dark-muted mb-1">Limite por produto</p>
                <p className="text-xl font-bold text-dark-text">{summary?.threshold ?? preview?.threshold ?? 100}</p>
              </div>
            </div>
            <div className="flex flex-wrap gap-2">
              {previewFilterOptions.map(option => (
                <button
                  key={option.key}
                  type="button"
                  onClick={() => setPreviewFilter(option.key)}
                  className={`inline-flex h-8 cursor-pointer items-center gap-2 rounded-lg border px-3 text-xs font-bold transition-colors ${
                    previewFilter === option.key
                      ? 'border-brand-primary bg-brand-primary/10 text-dark-text'
                      : 'border-dark-border bg-dark-input/45 text-dark-muted hover:text-dark-text'
                  }`}
                >
                  {option.label}
                  <span className="rounded-full bg-dark-card px-1.5 py-0.5 text-[10px] text-dark-muted">{option.count}</span>
                </button>
              ))}
            </div>

            <div className="max-h-[34rem] space-y-2 overflow-y-auto pr-1">
              {filteredPreviewProducts.map(product => {
                const accent = product.isReady ? statusStyles.sent.accent : statusStyles.pending.accent;

                return (
                <div
                  key={product.baseProduct}
                  className="rounded-xl border border-dark-border bg-dark-input/45 p-3"
                >
                  <div className="flex items-start justify-between gap-4">
                    <div className="min-w-0">
                      <p className={`truncate text-sm font-bold ${product.isReady ? 'text-dark-text' : 'text-dark-muted'}`}>
                        {product.baseProduct}
                      </p>
                      <p className="mt-1 text-[11px] font-semibold text-dark-muted">
                        {formatDelta(product.total_delta)} de {formatDelta(threshold)}
                      </p>
                    </div>
                    <span
                      className="rounded-full border px-2.5 py-1 text-[11px] font-bold"
                      style={product.isReady ? statusPillStyle('sent') : statusPillStyle('pending')}
                    >
                      {product.isReady ? 'Pronto' : `${Math.round(product.progress)}%`}
                    </span>
                  </div>
                  <div className="mt-3 h-1.5 overflow-hidden rounded-full bg-dark-border/70">
                    <div className="h-full rounded-full" style={{ width: `${product.progress}%`, backgroundColor: accent }} />
                  </div>
                </div>
                );
              })}
              {!filteredPreviewProducts.length && (
                <div className="rounded-xl border border-dark-border bg-dark-input/45 p-4 text-sm font-semibold text-dark-muted">
                  Nenhum produto nesta visualização.
                </div>
              )}
            </div>
          </div>
        </div>

        <div className="bg-dark-card border border-dark-border rounded-2xl p-6">
          <div className="mb-4 flex items-center gap-2">
            <Users className="w-5 h-5 text-brand-primary" />
            <h2 className="text-lg font-bold text-dark-text">Top clientes da campanha</h2>
          </div>
          <div className="divide-y divide-dark-border rounded-xl border border-dark-border overflow-hidden">
            {(preview?.customersPreview || []).map((customer, index) => (
              <div key={`${customer.fone}-${customer.nome}`} className="flex items-center justify-between gap-4 px-4 py-3">
                <div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-dark-input text-xs font-bold text-dark-muted">
                  {index + 1}
                </div>
                <div className="min-w-0">
                  <p className="font-semibold text-dark-text truncate">{customer.nome}</p>
                  <p className="text-xs text-dark-muted">{customer.fone}</p>
                </div>
                <span className="ml-auto text-xs font-bold text-brand-primary shrink-0">{customer.total_comprado || 0} un.</span>
              </div>
            ))}
            {!preview?.customersPreview.length && (
              <div className="p-4 text-sm font-semibold text-dark-muted">Nenhum cliente com telefone válido encontrado.</div>
            )}
          </div>
        </div>
      </div>

      <div className="bg-dark-card border border-dark-border rounded-2xl overflow-hidden">
        <div className="overflow-x-auto">
          <table className="w-full text-left text-sm">
            <thead className="bg-dark-header border-b border-dark-border text-dark-muted">
              <tr>
                <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Produto</th>
                <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Status</th>
                <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Delta</th>
                <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Itens</th>
                <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Tentativas</th>
                <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Atualizado</th>
                <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px] text-right">Ações</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-dark-border">
              {(summary?.groups || []).map(group => {
                const Icon = statusIcons[group.status];
                return (
                  <tr key={group.key} className="hover:bg-dark-input/40 transition-colors">
                    <td className="px-6 py-3">
                      <p className="font-semibold text-dark-text">{group.baseProductName}</p>
                      {group.lastError && <p className="text-xs text-red-400 mt-1 max-w-md truncate">{group.lastError}</p>}
                    </td>
                    <td className="px-6 py-3">
                      <span
                        className="inline-flex items-center gap-1.5 border px-2.5 py-1 rounded-full text-xs font-bold"
                        style={statusPillStyle(group.status)}
                      >
                        <Icon className="w-3.5 h-3.5" />
                        {statusLabels[group.status]}
                      </span>
                    </td>
                    <td className="px-6 py-3 font-bold text-dark-text">{formatDelta(group.totalDelta)}</td>
                    <td className="px-6 py-3 text-dark-muted">{group.rowCount}</td>
                    <td className="px-6 py-3 text-dark-muted">{group.attempts}</td>
                    <td className="px-6 py-3 text-dark-muted whitespace-nowrap">{formatDate(group.updatedAt)}</td>
                    <td className="px-6 py-3 text-right">
                      {(group.status === 'failed' || group.status === 'skipped') && (
                        <button
                          onClick={() => void handleRetry(group)}
                          disabled={isProcessing}
                          className="inline-flex items-center gap-1.5 text-xs font-bold text-brand-primary hover:opacity-80 disabled:opacity-50 cursor-pointer"
                        >
                          <RotateCcw className="w-3.5 h-3.5" />
                          Reprocessar
                        </button>
                      )}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
        {!summary?.groups.length && !isLoading && (
          <div className="p-8 text-center text-dark-muted">Nenhuma campanha registrada ainda.</div>
        )}
      </div>
        </div>
      )}
    </div>
  );
};

export default Campaigns;
