import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import {
  Plus,
  Eye,
  Pencil,
  FileDown,
  Link as LinkIcon,
  ArrowUpRight,
  SearchX,
  Send,
  FileText,
  PenLine,
  Mail,
  CheckCircle2,
  Wallet,
  TrendingUp,
  X,
} from "lucide-react";

import { PageHeader } from "@/components/page-header";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { SendProposalDialog } from "@/components/send-proposal-dialog";
import { ProposalStatusBadge } from "@/components/proposal-status-badge";
import { proposalsStore, useProposals } from "@/lib/store/proposals-store";
import { formatBRL, formatDate } from "@/lib/format";
import { generateProposalPdf } from "@/lib/pdf/proposal-pdf";
import { getEffectiveStatus, isExpired } from "@/lib/proposal-status";
import type {
  PaymentMethod,
  ProposalStatus,
  ProposalSummary,
} from "@/lib/mock/types";

type StatusFilter = "todos" | ProposalStatus;
type PaymentFilter = "todas" | PaymentMethod;
type ValidityFilter = "todas" | "validas" | "vencidas";

type SearchParams = {
  q?: string;
  status?: StatusFilter;
  payment?: PaymentFilter;
  validity?: ValidityFilter;
};

const STATUS_VALUES: StatusFilter[] = [
  "todos",
  "rascunho",
  "enviada",
  "aprovada",
  "expirada",
];
const PAYMENT_VALUES: PaymentFilter[] = ["todas", "pix", "boleto", "cartao"];
const VALIDITY_VALUES: ValidityFilter[] = ["todas", "validas", "vencidas"];

export const Route = createFileRoute("/_admin/propostas/")({
  validateSearch: (search: Record<string, unknown>): SearchParams => ({
    q:
      typeof search.q === "string" && search.q.length > 0 ? search.q : undefined,
    status:
      typeof search.status === "string" &&
      (STATUS_VALUES as string[]).includes(search.status)
        ? (search.status as StatusFilter)
        : undefined,
    payment:
      typeof search.payment === "string" &&
      (PAYMENT_VALUES as string[]).includes(search.payment)
        ? (search.payment as PaymentFilter)
        : undefined,
    validity:
      typeof search.validity === "string" &&
      (VALIDITY_VALUES as string[]).includes(search.validity)
        ? (search.validity as ValidityFilter)
        : undefined,
  }),
  component: PropostasPage,
});

const statusLabels: Record<string, string> = {
  rascunho: "rascunho",
  enviada: "enviada",
  aprovada: "aprovada",
  expirada: "vencida",
};

const paymentLabels: Record<PaymentMethod, string> = {
  pix: "Pix",
  boleto: "Boleto",
  cartao: "Cartão de crédito",
};

function matchesProposal(p: ProposalSummary, term: string): boolean {
  if (!term) return true;
  const t = term.toLowerCase().trim();
  if (!t) return true;

  const baseHaystack = [
    p.number,
    p.title,
    p.clientName,
    statusLabels[p.status] ?? p.status,
    String(p.total),
    formatBRL(p.total),
    p.recurringTotal ? formatBRL(p.recurringTotal) : "",
  ]
    .join(" ")
    .toLowerCase();

  if (baseHaystack.includes(t)) return true;

  const detail = proposalsStore.getDetail(p.id);
  if (detail) {
    const itemsHay = detail.items
      .map((i) => `${i.name} ${formatBRL(i.unitPrice)}`)
      .join(" ")
      .toLowerCase();
    if (itemsHay.includes(t)) return true;
  }

  return false;
}


function proposalPayments(p: ProposalSummary): PaymentMethod[] {
  const detail = proposalsStore.getDetail(p.id);
  if (!detail) return [];
  return detail.paymentMethods && detail.paymentMethods.length > 0
    ? detail.paymentMethods
    : [detail.paymentMethod];
}

function PropostasPage() {
  const proposals = useProposals();
  const navigate = useNavigate({ from: "/propostas" });
  const search = Route.useSearch();
  const urlQ = search.q;
  const status: StatusFilter = search.status ?? "todos";
  const payment: PaymentFilter = search.payment ?? "todas";
  const validity: ValidityFilter = search.validity ?? "todas";

  const [q, setQ] = useState(urlQ ?? "");
  const [sendProposal, setSendProposal] = useState<ProposalSummary | null>(null);

  useEffect(() => {
    setQ(urlQ ?? "");
  }, [urlQ]);

  // Debounce: input local → URL.
  useEffect(() => {
    const handle = setTimeout(() => {
      const current = urlQ ?? "";
      if (q === current) return;
      navigate({
        search: (prev: SearchParams) => ({ ...prev, q: q ? q : undefined }),
        replace: true,
      });
    }, 250);
    return () => clearTimeout(handle);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [q]);

  const filtered = useMemo(() => {
    return proposals.filter((p) => {
      if (!matchesProposal(p, q)) return false;

      const effective = getEffectiveStatus(p);
      if (status !== "todos" && effective !== status) return false;

      if (payment !== "todas") {
        const methods = proposalPayments(p);
        if (!methods.includes(payment)) return false;
      }

      if (validity === "validas" && isExpired(p)) return false;
      if (validity === "vencidas" && !isExpired(p)) return false;

      return true;
    });
  }, [proposals, q, status, payment, validity]);

  const stats = useMemo(() => {
    const sum = (list: ProposalSummary[]) =>
      list.reduce((acc, p) => acc + p.total, 0);
    const withEff = filtered.map((p) => ({ p, eff: getEffectiveStatus(p) }));
    const aprovada = withEff.filter((x) => x.eff === "aprovada").map((x) => x.p);
    return {
      total: filtered.length,
      rascunho: withEff.filter((x) => x.eff === "rascunho").length,
      enviada: withEff.filter((x) => x.eff === "enviada").length,
      aprovada: aprovada.length,
      pipelineValue: sum(filtered.filter((p) => getEffectiveStatus(p) !== "aprovada")),
      approvedValue: sum(aprovada),
    };
  }, [filtered]);

  const hasFilters =
    !!urlQ || status !== "todos" || payment !== "todas" || validity !== "todas";

  const handleCopyLink = async (p: ProposalSummary) => {
    const url =
      typeof window !== "undefined"
        ? `${window.location.origin}/p/${p.slug}`
        : `/p/${p.slug}`;
    try {
      await navigator.clipboard.writeText(url);
      toast.success("Link público copiado", { description: url });
    } catch {
      toast.error("Não foi possível copiar o link", {
        description: "Copie manualmente: " + url,
      });
    }
  };

  const handleDownloadPdf = (p: ProposalSummary) => {
    const detail = proposalsStore.getDetail(p.id);
    if (!detail) {
      toast.error("PDF indisponível", {
        description: "Esta proposta ainda não tem detalhes para gerar PDF.",
      });
      return;
    }
    try {
      generateProposalPdf(p, detail);
      toast.success("PDF gerado", { description: `Proposta #${p.number}` });
    } catch (err) {
      console.error(err);
      toast.error("Falha ao gerar PDF");
    }
  };

  const clearFilters = () => {
    setQ("");
    navigate({ search: {}, replace: true });
  };

  const handleMarkSent = (p: ProposalSummary) => {
    proposalsStore.setStatus(p.id, "enviada");
    toast.success("Proposta marcada como enviada", {
      description: `#${p.number} · ${p.clientName}`,
    });
  };

  const handleMarkApproved = (p: ProposalSummary) => {
    proposalsStore.setStatus(p.id, "aprovada");
    toast.success("Proposta marcada como aprovada", {
      description: `#${p.number} · ${p.clientName}`,
    });
  };

  return (
    <div className="space-y-8">
      <PageHeader
        title="Propostas"
        description="Acompanhe rascunhos, envios e aprovações de propostas comerciais."
        actions={
          <Button asChild className="bg-gradient-brand text-white shadow-soft">
            <Link to="/propostas/nova">
              <Plus className="h-4 w-4" /> Nova proposta
            </Link>
          </Button>
        }
      />

      {/* ---------- Pipeline cards ---------- */}
      <section className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6">
        <StatCard
          icon={FileText}
          label="Total"
          value={String(stats.total)}
          tint="primary"
        />
        <StatCard
          icon={PenLine}
          label="Rascunhos"
          value={String(stats.rascunho)}
          tint="muted"
        />
        <StatCard
          icon={Mail}
          label="Enviadas"
          value={String(stats.enviada)}
          tint="primary"
        />
        <StatCard
          icon={CheckCircle2}
          label="Aprovadas"
          value={String(stats.aprovada)}
          tint="success"
        />
        <StatCard
          icon={Wallet}
          label="Pipeline"
          value={formatBRL(stats.pipelineValue)}
          tint="primary"
          compact
        />
        <StatCard
          icon={TrendingUp}
          label="Aprovado"
          value={formatBRL(stats.approvedValue)}
          tint="success"
          compact
        />
      </section>

      {/* ---------- Filters ---------- */}
      <div className="space-y-3">
        <div className="flex flex-wrap items-center gap-3">
          <Input
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder="Buscar por número, título, cliente, serviço ou valor..."
            className="max-w-md flex-1 min-w-[220px]"
          />

          <Select
            value={status}
            onValueChange={(v) =>
              navigate({
                search: (prev: SearchParams) => ({
                  ...prev,
                  status: v === "todos" ? undefined : (v as StatusFilter),
                }),
                replace: true,
              })
            }
          >
            <SelectTrigger className="w-[170px]">
              <SelectValue placeholder="Status" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="todos">Todos os status</SelectItem>
              <SelectItem value="rascunho">Rascunho</SelectItem>
              <SelectItem value="enviada">Enviada</SelectItem>
              <SelectItem value="aprovada">Aprovada</SelectItem>
              <SelectItem value="expirada">Vencida</SelectItem>
            </SelectContent>
          </Select>

          <Select
            value={payment}
            onValueChange={(v) =>
              navigate({
                search: (prev: SearchParams) => ({
                  ...prev,
                  payment: v === "todas" ? undefined : (v as PaymentFilter),
                }),
                replace: true,
              })
            }
          >
            <SelectTrigger className="w-[190px]">
              <SelectValue placeholder="Forma de pagamento" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="todas">Todas as formas</SelectItem>
              <SelectItem value="pix">{paymentLabels.pix}</SelectItem>
              <SelectItem value="boleto">{paymentLabels.boleto}</SelectItem>
              <SelectItem value="cartao">{paymentLabels.cartao}</SelectItem>
            </SelectContent>
          </Select>

          <Select
            value={validity}
            onValueChange={(v) =>
              navigate({
                search: (prev: SearchParams) => ({
                  ...prev,
                  validity: v === "todas" ? undefined : (v as ValidityFilter),
                }),
                replace: true,
              })
            }
          >
            <SelectTrigger className="w-[170px]">
              <SelectValue placeholder="Validade" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="todas">Todas as validades</SelectItem>
              <SelectItem value="validas">Apenas válidas</SelectItem>
              <SelectItem value="vencidas">Apenas vencidas</SelectItem>
            </SelectContent>
          </Select>

          {hasFilters && (
            <Button
              variant="ghost"
              size="sm"
              onClick={clearFilters}
              className="text-muted-foreground hover:text-foreground"
            >
              <X className="h-4 w-4" /> Limpar filtros
            </Button>
          )}

          <div className="ml-auto text-sm text-muted-foreground">
            {filtered.length} de {proposals.length}
          </div>
        </div>
      </div>

      <Card className="overflow-hidden border-border/60 shadow-soft">
        <div className="overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow className="bg-muted/40 hover:bg-muted/40">
                <TableHead className="w-[110px]">Número</TableHead>
                <TableHead>Cliente / Título</TableHead>
                <TableHead>Status</TableHead>
                <TableHead>Validade</TableHead>
                <TableHead className="text-right">Valor</TableHead>
                <TableHead className="text-right">Ações</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filtered.map((p) => {
                const effective = getEffectiveStatus(p);
                const canMarkSent = effective === "rascunho";
                const canMarkApproved =
                  effective === "rascunho" || effective === "enviada" || effective === "expirada";
                return (
                <TableRow key={p.id} className="group">
                  <TableCell className="font-mono text-xs text-muted-foreground">
                    #{p.number}
                  </TableCell>
                  <TableCell>
                    <div className="font-medium">{p.clientName}</div>
                    <div className="text-xs text-muted-foreground">{p.title}</div>
                  </TableCell>
                  <TableCell>
                    <ProposalStatusBadge status={effective} />
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground">
                    {formatDate(p.validUntil)}
                  </TableCell>
                  <TableCell className="text-right">
                    <div className="font-display font-semibold">
                      {formatBRL(p.total)}
                    </div>
                    {p.recurringTotal ? (
                      <div className="text-xs text-muted-foreground">
                        + {formatBRL(p.recurringTotal)}/mês
                      </div>
                    ) : null}
                  </TableCell>
                  <TableCell>
                    <div className="flex justify-end gap-1 opacity-80 transition group-hover:opacity-100">
                      <Button
                        asChild
                        size="sm"
                        variant="outline"
                        className="h-8 gap-1 border-primary/30 text-primary hover:bg-primary/5"
                      >
                        <Link to="/propostas/$id" params={{ id: p.id }}>
                          Ver detalhes <ArrowUpRight className="h-3.5 w-3.5" />
                        </Link>
                      </Button>
                      <Button
                        asChild
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        title="Ver proposta pública"
                      >
                        <Link to="/p/$slug" params={{ slug: p.slug }} target="_blank">
                          <Eye className="h-4 w-4" />
                        </Link>
                      </Button>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        title="Copiar link público"
                        onClick={() => handleCopyLink(p)}
                      >
                        <LinkIcon className="h-4 w-4" />
                      </Button>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        title="Baixar PDF"
                        onClick={() => handleDownloadPdf(p)}
                      >
                        <FileDown className="h-4 w-4" />
                      </Button>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8 text-primary hover:bg-primary/5"
                        title="Enviar proposta"
                        onClick={() => setSendProposal(p)}
                      >
                        <Send className="h-4 w-4" />
                      </Button>
                      {canMarkSent && (
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8 text-primary hover:bg-primary/5"
                          title="Marcar como enviada"
                          onClick={() => handleMarkSent(p)}
                        >
                          <Mail className="h-4 w-4" />
                        </Button>
                      )}
                      {canMarkApproved && (
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8 text-success hover:bg-success/10"
                          title="Marcar como aprovada"
                          onClick={() => handleMarkApproved(p)}
                        >
                          <CheckCircle2 className="h-4 w-4" />
                        </Button>
                      )}
                      <Button
                        asChild
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        title="Editar proposta"
                      >
                        <Link to="/propostas/$id/editar" params={{ id: p.id }}>
                          <Pencil className="h-4 w-4" />
                        </Link>
                      </Button>
                    </div>
                  </TableCell>
                </TableRow>
                );
              })}
              {filtered.length === 0 && (
                <TableRow>
                  <TableCell colSpan={6} className="py-16 text-center">
                    <div className="mx-auto flex max-w-sm flex-col items-center gap-3 text-muted-foreground">
                      <div className="flex h-12 w-12 items-center justify-center rounded-full bg-muted">
                        <SearchX className="h-5 w-5" />
                      </div>
                      <div className="font-display text-base font-semibold text-foreground">
                        {proposals.length === 0
                          ? "Nenhuma proposta cadastrada"
                          : "Nenhum resultado encontrado"}
                      </div>
                      <p className="text-sm">
                        {proposals.length === 0
                          ? "Crie sua primeira proposta para começar a acompanhar seu pipeline comercial."
                          : "Tente ajustar a busca ou limpar os filtros aplicados."}
                      </p>
                      {proposals.length === 0 ? (
                        <Button asChild size="sm" className="bg-gradient-brand text-white">
                          <Link to="/propostas/nova">
                            <Plus className="h-4 w-4" /> Nova proposta
                          </Link>
                        </Button>
                      ) : hasFilters ? (
                        <Button variant="outline" size="sm" onClick={clearFilters}>
                          <X className="h-4 w-4" /> Limpar filtros
                        </Button>
                      ) : null}
                    </div>
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      </Card>

      <SendProposalDialog
        open={sendProposal !== null}
        onOpenChange={(o) => !o && setSendProposal(null)}
        proposal={sendProposal}
      />
    </div>
  );
}

// ---------- Subcomponents ----------

function StatCard({
  icon: Icon,
  label,
  value,
  tint,
  compact,
}: {
  icon: React.ComponentType<{ className?: string }>;
  label: string;
  value: string;
  tint: "primary" | "success" | "muted";
  compact?: boolean;
}) {
  const tintClass =
    tint === "success"
      ? "bg-success/15 text-success"
      : tint === "muted"
        ? "bg-muted text-muted-foreground"
        : "bg-gradient-brand text-white";

  return (
    <Card className="border-border/60 shadow-soft transition hover:-translate-y-0.5 hover:shadow-glow">
      <CardContent className="flex items-center gap-3 p-4">
        <div
          className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-lg ${tintClass}`}
        >
          <Icon className="h-4 w-4" />
        </div>
        <div className="min-w-0">
          <div className="text-xs uppercase tracking-wider text-muted-foreground">
            {label}
          </div>
          <div
            className={`font-display font-semibold ${compact ? "text-lg" : "text-2xl"} truncate`}
          >
            {value}
          </div>
        </div>
      </CardContent>
    </Card>
  );
}
