"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import {
  Search,
  SlidersHorizontal,
  Download,
  FileDown,
  ChevronLeft,
  ChevronRight,
} from "lucide-react";

import { Breadcrumb } from "@/shared/components/ui/breadcrumb";
import { Card, CardContent } from "@/shared/components/ui/card";
import { Input } from "@/shared/components/ui/input";
import { Button } from "@/shared/components/ui/button";
import { Label } from "@/shared/components/ui/label";
import { Checkbox } from "@/shared/components/ui/checkbox";
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/shared/components/ui/table";
import {
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
  DrawerFooter,
  DrawerClose,
} from "@/shared/components/ui/drawer";
import { useDebouncedValue } from "@/shared/hooks/use-debounced-value";
import { buildPageNumbers } from "@/shared/utils/build-page-numbers";
import { downloadCsv } from "@/shared/utils/download-csv";
import { getAllContactListsAction } from "../actions/get-all-contact-lists-action";
import { getExportHistoryAction } from "../actions/get-export-history-action";
import { exportContactsAction } from "../actions/export-contacts-action";
import { downloadContactExportAction } from "../actions/download-contact-export-action";

type ContactStatus = "ACTIVE" | "UNSUBSCRIBED" | "BOUNCED";

const COLUMN_OPTIONS: { value: string; label: string }[] = [
  { value: "name", label: "Nome" },
  { value: "email", label: "E-mail" },
  { value: "phone", label: "Telefone" },
  { value: "tags", label: "Tags" },
  { value: "status", label: "Status" },
  { value: "source", label: "Origem" },
  { value: "createdAt", label: "Data de Criação" },
  { value: "lists", label: "Listas" },
];

interface ContactListOption {
  id: string;
  name: string;
}

interface ExportHistoryItem {
  id: string;
  filters: Record<string, unknown>;
  columns: string[];
  totalRows: number;
  createdAt: string;
}

const PAGE_SIZE_OPTIONS = [20, 50, 100];

function describeFilters(filters: Record<string, unknown>): string {
  const parts: string[] = [];
  if (filters.search) parts.push(`busca "${filters.search}"`);
  if (filters.status) parts.push(`status ${filters.status}`);
  if (filters.tag) parts.push(`tag "${filters.tag}"`);
  if (filters.listId) parts.push("lista específica");
  if (filters.openedWithinDays) parts.push(`abriu e-mail em ${filters.openedWithinDays}d`);
  if (filters.subscribedWithinDays) parts.push(`inscrito em ${filters.subscribedWithinDays}d`);
  return parts.length > 0 ? parts.join(", ") : "Todos os contatos";
}

export function ContactsExportPageView() {
  const [status, setStatus] = useState<ContactStatus | "">("");
  const [tag, setTag] = useState("");
  const [listId, setListId] = useState("");
  const [openedWithin30, setOpenedWithin30] = useState(false);
  const [subscribedWithin30, setSubscribedWithin30] = useState(false);
  const [columns, setColumns] = useState<string[]>(COLUMN_OPTIONS.map((c) => c.value));
  const [lists, setLists] = useState<ContactListOption[]>([]);
  const [isGenerating, setIsGenerating] = useState(false);

  const [history, setHistory] = useState<ExportHistoryItem[]>([]);
  const [isLoadingHistory, setIsLoadingHistory] = useState(true);

  const [drawerOpen, setDrawerOpen] = useState(false);
  const [searchInput, setSearchInput] = useState("");
  const search = useDebouncedValue(searchInput, 400);

  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);

  useEffect(() => {
    getAllContactListsAction()
      .then((data) => setLists(data.lists ?? []))
      .catch(() => {});
  }, []);

  const loadHistory = useCallback(() => {
    setIsLoadingHistory(true);
    getExportHistoryAction()
      .then((data) => setHistory(data.exports ?? []))
      .catch(() => {})
      .finally(() => setIsLoadingHistory(false));
  }, []);

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

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

  const filteredHistory = useMemo(() => {
    if (!search.trim()) return history;
    const term = search.toLowerCase();
    return history.filter((item) => {
      const filterDesc = describeFilters(item.filters).toLowerCase();
      const dateStr = new Date(item.createdAt).toLocaleString("pt-BR").toLowerCase();
      return filterDesc.includes(term) || dateStr.includes(term);
    });
  }, [history, search]);

  const totalPages = Math.max(1, Math.ceil(filteredHistory.length / pageSize));
  const pageNumbers = useMemo(() => buildPageNumbers(page, totalPages), [page, totalPages]);
  const currentPageItems = useMemo(() => {
    const start = (page - 1) * pageSize;
    return filteredHistory.slice(start, start + pageSize);
  }, [filteredHistory, page, pageSize]);

  function toggleColumn(value: string) {
    setColumns((prev) => (prev.includes(value) ? prev.filter((c) => c !== value) : [...prev, value]));
  }

  async function handleGenerate() {
    setIsGenerating(true);
    try {
      const body: Record<string, unknown> = { columns };
      if (status) body.status = status;
      if (tag) body.tag = tag;
      if (listId) body.listId = listId;
      if (openedWithin30) body.openedWithinDays = 30;
      if (subscribedWithin30) body.subscribedWithinDays = 30;

      const data = await exportContactsAction(body);
      const { csvContent, fileName } = await downloadContactExportAction(data.exportId);

      toast.success(`Exportação gerada com ${data.totalRows} contato(s).`);
      setDrawerOpen(false);
      downloadCsv(csvContent, fileName);
      loadHistory();
    } catch {
      toast.error("Não foi possível gerar a exportação.");
    } finally {
      setIsGenerating(false);
    }
  }

  return (
    <div className="space-y-4">
      {/* Header with Breadcrumb and Action */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3">
        <Breadcrumb
          className="text-sm"
          items={[
            { label: "Início", href: "/" },
            { label: "Contatos", href: "/contacts" },
            { label: "Exportar" },
          ]}
        />
        <Drawer open={drawerOpen} onOpenChange={setDrawerOpen}>
          <DrawerTrigger
            render={
              <Button className="h-9">
                <SlidersHorizontal className="w-4 h-4" />
                Filtrar
              </Button>
            }
          />
            <DrawerContent className="max-w-md font-sans">
              <DrawerHeader>
                <DrawerTitle className="text-lg font-bold text-zinc-900 flex items-center gap-2">
                  <SlidersHorizontal className="w-5 h-5 text-indigo-600" />
                  Filtros do Export
                </DrawerTitle>
                <DrawerDescription className="text-xs text-zinc-500">
                  Configure os critérios dos contatos e as colunas desejadas para gerar o arquivo CSV.
                </DrawerDescription>
              </DrawerHeader>

              <div className="flex-1 overflow-y-auto px-6 py-2 space-y-5">
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                  <div className="space-y-1.5">
                    <Label className="text-xs font-semibold text-zinc-700">Status</Label>
                    <select
                      value={status}
                      onChange={(e) => setStatus(e.target.value as ContactStatus | "")}
                      className="w-full h-10 rounded-lg border border-zinc-300 bg-white px-2.5 text-xs text-zinc-800"
                    >
                      <option value="">Todos</option>
                      <option value="ACTIVE">Ativo</option>
                      <option value="UNSUBSCRIBED">Descadastrado</option>
                      <option value="BOUNCED">Inválido</option>
                    </select>
                  </div>

                  <div className="space-y-1.5">
                    <Label className="text-xs font-semibold text-zinc-700">Lista</Label>
                    <select
                      value={listId}
                      onChange={(e) => setListId(e.target.value)}
                      className="w-full h-10 rounded-lg border border-zinc-300 bg-white px-2.5 text-xs text-zinc-800"
                    >
                      <option value="">Todas</option>
                      {lists.map((l) => (
                        <option key={l.id} value={l.id}>
                          {l.name}
                        </option>
                      ))}
                    </select>
                  </div>
                </div>

                <div className="space-y-1.5">
                  <Label className="text-xs font-semibold text-zinc-700">Tag</Label>
                  <Input
                    value={tag}
                    onChange={(e) => setTag(e.target.value)}
                    placeholder="Nome da tag"
                    className="h-10 text-xs"
                  />
                </div>

                <div className="space-y-2">
                  <Label className="text-xs font-semibold text-zinc-700">Filtros Rápidos</Label>
                  <div className="flex flex-wrap gap-2">
                    <button
                      type="button"
                      onClick={() => setOpenedWithin30((v) => !v)}
                      className={`text-xs font-semibold h-8 px-3 rounded-full border transition-colors cursor-pointer ${
                        openedWithin30
                          ? "bg-indigo-600 border-indigo-600 text-white"
                          : "border-zinc-300 text-zinc-700 hover:bg-zinc-100 bg-white"
                      }`}
                    >
                      Abriu um e-mail — últimos 30 dias
                    </button>
                    <button
                      type="button"
                      onClick={() => setSubscribedWithin30((v) => !v)}
                      className={`text-xs font-semibold h-8 px-3 rounded-full border transition-colors cursor-pointer ${
                        subscribedWithin30
                          ? "bg-indigo-600 border-indigo-600 text-white"
                          : "border-zinc-300 text-zinc-700 hover:bg-zinc-100 bg-white"
                      }`}
                    >
                      Inscrito nos últimos 30 dias
                    </button>
                  </div>
                </div>

                <div className="space-y-2 pt-2 border-t border-zinc-100">
                  <Label className="text-xs font-semibold text-zinc-700">Colunas a incluir</Label>
                  <div className="grid grid-cols-2 gap-2.5">
                    {COLUMN_OPTIONS.map((col) => (
                      <label key={col.value} className="flex items-center gap-2 text-xs text-zinc-700 cursor-pointer select-none">
                        <Checkbox checked={columns.includes(col.value)} onCheckedChange={() => toggleColumn(col.value)} />
                        {col.label}
                      </label>
                    ))}
                  </div>
                </div>
              </div>

              <DrawerFooter className="flex flex-row items-center justify-end gap-2 px-6 py-4 border-t border-zinc-100 bg-zinc-50/50">
                <DrawerClose
                  render={
                    <Button variant="outline" size="sm" className="h-9 font-semibold">
                      Cancelar
                    </Button>
                  }
                />
                <Button
                  size="sm"
                  className="h-9 font-semibold"
                  onClick={handleGenerate}
                  disabled={isGenerating || columns.length === 0}
                >
                  <FileDown className="w-4 h-4 mr-1.5" />
                  {isGenerating ? "Gerando..." : "Gerar exportação"}
                </Button>
              </DrawerFooter>
            </DrawerContent>
          </Drawer>
      </div>

      {/* Search Banner */}
      <div className="text-center space-y-4 py-2">
        <h1 className="text-2xl sm:text-[26px] font-extrabold text-zinc-900 leading-snug">
          Encontre as exportações que você precisa
        </h1>

        <div className="relative max-w-xl mx-auto">
          <Search className="w-4 h-4 text-zinc-400 absolute left-4 top-1/2 -translate-y-1/2 pointer-events-none" />
          <Input
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            placeholder="Pesquisar exportações..."
            className="pl-10 h-11 rounded-full"
          />
        </div>
      </div>

      {/* Main Exports History Table Card */}
      <Card className="bg-white border border-zinc-200/80 rounded-2xl shadow-xs overflow-hidden">
        <CardContent className="p-0">
          <div className="overflow-x-auto w-full">
            <Table className="w-full text-left text-xs">
              <TableHeader className="bg-zinc-50 border-b border-zinc-200">
                <TableRow className="hover:bg-transparent border-zinc-200">
                  <TableHead className="text-xs font-bold uppercase text-zinc-700 py-3.5 px-5">Data</TableHead>
                  <TableHead className="text-xs font-bold uppercase text-zinc-700 py-3.5 px-4">Filtro Usado</TableHead>
                  <TableHead className="text-xs font-bold uppercase text-zinc-700 py-3.5 px-4">Total</TableHead>
                  <TableHead className="text-xs font-bold uppercase text-zinc-700 text-right w-24 py-3.5 px-5">Ação</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {isLoadingHistory ? (
                  <TableRow>
                    <TableCell colSpan={4} className="text-center py-10 text-zinc-500">
                      Carregando...
                    </TableCell>
                  </TableRow>
                ) : filteredHistory.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={4} className="text-center py-10 text-zinc-500">
                      Nenhuma exportação encontrada.
                    </TableCell>
                  </TableRow>
                ) : (
                  currentPageItems.map((item) => (
                    <TableRow key={item.id} className="border-b border-zinc-100 hover:bg-zinc-50/80">
                      <TableCell className="py-3.5 px-5 font-medium text-zinc-900">
                        {new Date(item.createdAt).toLocaleString("pt-BR")}
                      </TableCell>
                      <TableCell className="text-zinc-600 py-3.5 px-4">{describeFilters(item.filters)}</TableCell>
                      <TableCell className="py-3.5 px-4 font-bold text-zinc-800">{item.totalRows}</TableCell>
                      <TableCell className="text-right py-3.5 px-5">
                        <button
                          type="button"
                          onClick={async () => {
                            try {
                              const { csvContent, fileName } = await downloadContactExportAction(item.id);
                              downloadCsv(csvContent, fileName);
                            } catch {
                              toast.error("Não foi possível baixar a exportação.");
                            }
                          }}
                          className="inline-flex items-center gap-1.5 text-indigo-600 hover:text-indigo-800 font-semibold cursor-pointer"
                        >
                          <Download className="w-3.5 h-3.5" />
                          Baixar
                        </button>
                      </TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>

      {/* Footer Controls */}
      {!isLoadingHistory && filteredHistory.length > 0 && (
        <div className="flex flex-col sm:flex-row items-center justify-between gap-3 pt-1">
          <div className="flex items-center gap-2 text-xs text-zinc-500">
            <span>Linhas:</span>
            <select
              value={pageSize}
              onChange={(e) => setPageSize(Number(e.target.value))}
              className="h-8 rounded-lg border border-zinc-300 bg-white px-2 text-xs text-zinc-700"
            >
              {PAGE_SIZE_OPTIONS.map((size) => (
                <option key={size} value={size}>
                  {size}
                </option>
              ))}
            </select>
          </div>

          <div className="flex items-center gap-1.5">
            <button
              type="button"
              onClick={() => setPage((p) => Math.max(1, p - 1))}
              disabled={page <= 1}
              aria-label="Página anterior"
              className="h-8 w-8 inline-flex items-center justify-center rounded-lg border border-zinc-300 text-zinc-700 hover:bg-zinc-100 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
            >
              <ChevronLeft className="w-4 h-4" />
            </button>
            {pageNumbers.map((p, idx) =>
              p === "..." ? (
                <span key={`ellipsis-${idx}`} className="text-xs text-zinc-400 px-1">
                  ...
                </span>
              ) : (
                <button
                  key={p}
                  type="button"
                  onClick={() => setPage(p)}
                  className={`text-xs font-semibold h-8 w-8 rounded-lg cursor-pointer ${
                    p === page
                      ? "bg-[#635BFF] text-white"
                      : "text-zinc-700 hover:bg-zinc-100"
                  }`}
                >
                  {p}
                </button>
              )
            )}
            <button
              type="button"
              onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
              disabled={page >= totalPages}
              aria-label="Próxima página"
              className="h-8 w-8 inline-flex items-center justify-center rounded-lg border border-zinc-300 text-zinc-700 hover:bg-zinc-100 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
            >
              <ChevronRight className="w-4 h-4" />
            </button>
          </div>

          <div className="flex items-center gap-1.5 text-xs text-zinc-500">
            <span>Ir para a página</span>
            <Input
              type="number"
              min={1}
              max={totalPages}
              className="h-8 w-16 px-2"
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  const value = Number((e.target as HTMLInputElement).value);
                  if (value >= 1 && value <= totalPages) setPage(value);
                }
              }}
            />
          </div>
        </div>
      )}
    </div>
  );
}
