import { useEffect, useMemo, useState, type ReactNode } from "react";
import {
  ArchiveRestore,
  BadgeDollarSign,
  Building2,
  Check,
  ChevronLeft,
  ChevronRight,
  CircleDollarSign,
  Edit3,
  Layers3,
  Loader2,
  Plus,
  RefreshCw,
  Search,
  Settings2,
} from "lucide-react";
import { toast } from "sonner";

import { SearchableSelect } from "@/components/board/SearchableSelect";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import { Switch } from "@/components/ui/switch";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Textarea } from "@/components/ui/textarea";
import { useAppLists } from "@/lib/appLists";
import {
  buildTariffRowId,
  saveTariffCatalogRow,
  setTariffCatalogRowActive,
  useTariffCatalog,
  type TariffCatalogRow,
  type TariffCatalogUpsertInput,
} from "@/lib/tariffCatalog";
import {
  buildTariffSectionId,
  saveTariffSection,
  setTariffSectionActive,
  slugifyTariffValue,
  useTariffSections,
  type TariffSection,
  type TariffSectionInput,
  type TariffSectionScope,
} from "@/lib/tariffSections";
import { cn } from "@/lib/utils";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

type SectionFilter = "general" | "client";

type SectionDraft = TariffSectionInput;

type RowDraft = TariffCatalogUpsertInput;

const SECTION_PAGE_SIZE = 6;
const TARIFF_PAGE_SIZE = 10;

function formatMoney(value: number | null | undefined) {
  if (value == null || !Number.isFinite(Number(value))) return "—";
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    maximumFractionDigits: 2,
  }).format(Number(value));
}

function numericValue(value: string) {
  const parsed = Number(String(value || "").replace(/,/g, "").trim());
  return Number.isFinite(parsed) ? parsed : null;
}

function buildReference(min: number | null, max: number | null) {
  if (min == null && max == null) return "";
  if (min != null && max != null && min !== max) return `${min} - ${max}`;
  return String(min ?? max ?? "");
}

function blankSection(scope: TariffSectionScope, sections: TariffSection[]): SectionDraft {
  const maxOrder = sections.reduce((max, section) => Math.max(max, section.sortOrder), 0);
  const name = scope === "client" ? "Tarifario especial" : "Nueva sección";

  return {
    id: buildTariffSectionId(scope, name),
    name,
    scope,
    clientName: "",
    pricingMode: scope === "client" ? "fixed_multi" : "guided",
    allowManual: true,
    description: "",
    sortOrder: maxOrder + 10,
    isActive: true,
  };
}

function sectionToDraft(section: TariffSection): SectionDraft {
  return {
    id: section.id,
    name: section.name,
    scope: section.scope,
    clientName: section.clientName,
    pricingMode: section.pricingMode,
    allowManual: section.allowManual,
    description: section.description,
    sortOrder: section.sortOrder,
    isActive: section.isActive,
  };
}

function blankRow(section: TariffSection, rows: TariffCatalogRow[]): RowDraft {
  const sectionRows = rows.filter((row) => row.section === section.id);
  const maxOrder = sectionRows.reduce((max, row) => Math.max(max, row.sort_order), 0);
  const isSpecial = section.scope === "client";

  return {
    id: "",
    catalog_item_id: "",
    section: section.id,
    category: isSpecial ? section.name : "",
    service: "",
    notes: "",
    work_type_id: isSpecial ? "special_fixed" : "",
    work_type_label: isSpecial ? "Tarifa fija" : "",
    work_type_short_label: isSpecial ? "Fijo" : "",
    hour_reference: "",
    level_id: isSpecial ? "fixed" : "",
    level_label: isSpecial ? "Precio fijo" : "",
    reference: "",
    reference_min: null,
    reference_max: null,
    level_hint: "",
    sort_order: maxOrder + 1,
    is_active: true,
    managed_by: "app",
  };
}

function rowToDraft(row: TariffCatalogRow): RowDraft {
  return {
    id: row.id,
    catalog_item_id: row.catalog_item_id,
    section: row.section,
    category: row.category,
    service: row.service,
    notes: row.notes,
    work_type_id: row.work_type_id,
    work_type_label: row.work_type_label,
    work_type_short_label: row.work_type_short_label,
    hour_reference: row.hour_reference,
    level_id: row.level_id,
    level_label: row.level_label,
    reference: row.reference,
    reference_min: row.reference_min,
    reference_max: row.reference_max,
    level_hint: row.level_hint,
    sort_order: row.sort_order,
    is_active: row.is_active,
    managed_by: "app",
  };
}

export function TariffManagerDialog({ open, onOpenChange }: Props) {
  const { lists } = useAppLists();
  const {
    sections,
    loading: sectionsLoading,
    error: sectionsError,
    refresh: refreshSections,
  } = useTariffSections();
  const {
    rows,
    loading: rowsLoading,
    error: rowsError,
    refresh: refreshRows,
  } = useTariffCatalog();

  const [filter, setFilter] = useState<SectionFilter>("general");
  const [selectedSectionId, setSelectedSectionId] = useState<string>("");
  const [search, setSearch] = useState("");
  const [showInactiveRows, setShowInactiveRows] = useState(false);
  const [sectionEditorOpen, setSectionEditorOpen] = useState(false);
  const [sectionDraft, setSectionDraft] = useState<SectionDraft | null>(null);
  const [editingSection, setEditingSection] = useState<TariffSection | null>(null);
  const [rowEditorOpen, setRowEditorOpen] = useState(false);
  const [rowDraft, setRowDraft] = useState<RowDraft | null>(null);
  const [editingRow, setEditingRow] = useState<TariffCatalogRow | null>(null);
  const [savingSection, setSavingSection] = useState(false);
  const [savingRow, setSavingRow] = useState(false);
  const [changingActiveId, setChangingActiveId] = useState<string | null>(null);
  const [sectionPage, setSectionPage] = useState(1);
  const [tariffPage, setTariffPage] = useState(1);

  const filteredSections = useMemo(
    () =>
      sections.filter((section) => section.scope === filter).sort((a, b) => {
        if (a.isActive !== b.isActive) return a.isActive ? -1 : 1;
        return a.sortOrder - b.sortOrder || a.name.localeCompare(b.name);
      }),
    [filter, sections],
  );

  const sectionPageCount = Math.max(1, Math.ceil(filteredSections.length / SECTION_PAGE_SIZE));
  const paginatedSections = useMemo(() => {
    const start = (sectionPage - 1) * SECTION_PAGE_SIZE;
    return filteredSections.slice(start, start + SECTION_PAGE_SIZE);
  }, [filteredSections, sectionPage]);

  const selectedSection =
    sections.find((section) => section.id === selectedSectionId) || filteredSections[0] || null;

  useEffect(() => {
    if (!selectedSection && filteredSections.length) {
      setSelectedSectionId(filteredSections[0].id);
      return;
    }

    if (selectedSection && selectedSection.scope !== filter) {
      setSelectedSectionId(filteredSections[0]?.id || "");
    }
  }, [filter, filteredSections, selectedSection]);

  useEffect(() => {
    if (!open) return;
    void Promise.all([refreshSections(), refreshRows()]);
  }, [open, refreshRows, refreshSections]);

  useEffect(() => {
    setSectionPage(1);
  }, [filter]);

  useEffect(() => {
    setSectionPage((current) => Math.min(current, sectionPageCount));
  }, [sectionPageCount]);

  useEffect(() => {
    if (!selectedSectionId) return;
    const selectedIndex = filteredSections.findIndex((section) => section.id === selectedSectionId);
    if (selectedIndex < 0) return;
    const selectedPage = Math.floor(selectedIndex / SECTION_PAGE_SIZE) + 1;
    setSectionPage(selectedPage);
  }, [filteredSections, selectedSectionId]);

  const selectedRows = useMemo(() => {
    if (!selectedSection) return [];
    const query = search.trim().toLowerCase();

    return rows
      .filter((row) => row.section === selectedSection.id)
      .filter((row) => showInactiveRows || row.is_active)
      .filter((row) => {
        if (!query) return true;
        return [row.category, row.service, row.work_type_label, row.level_label, row.notes]
          .join(" ")
          .toLowerCase()
          .includes(query);
      })
      .sort((a, b) => a.sort_order - b.sort_order || a.service.localeCompare(b.service));
  }, [rows, search, selectedSection, showInactiveRows]);

  const tariffPageCount = Math.max(1, Math.ceil(selectedRows.length / TARIFF_PAGE_SIZE));
  const paginatedRows = useMemo(() => {
    const start = (tariffPage - 1) * TARIFF_PAGE_SIZE;
    return selectedRows.slice(start, start + TARIFF_PAGE_SIZE);
  }, [selectedRows, tariffPage]);

  useEffect(() => {
    setTariffPage(1);
  }, [search, selectedSection?.id, showInactiveRows]);

  useEffect(() => {
    setTariffPage((current) => Math.min(current, tariffPageCount));
  }, [tariffPageCount]);

  const totalActiveRows = rows.filter((row) => row.is_active).length;
  const totalSpecialSections = sections.filter(
    (section) => section.scope === "client" && section.isActive,
  ).length;

  const changeSectionPage = (nextPage: number) => {
    const page = Math.min(Math.max(nextPage, 1), sectionPageCount);
    setSectionPage(page);

    const firstSectionOnPage = filteredSections[(page - 1) * SECTION_PAGE_SIZE];
    if (firstSectionOnPage) setSelectedSectionId(firstSectionOnPage.id);
  };

  const openNewSection = (scope: TariffSectionScope) => {
    setEditingSection(null);
    setSectionDraft(blankSection(scope, sections));
    setSectionEditorOpen(true);
  };

  const openEditSection = (section: TariffSection) => {
    setEditingSection(section);
    setSectionDraft(sectionToDraft(section));
    setSectionEditorOpen(true);
  };

  const saveSection = async () => {
    if (!sectionDraft) return;

    const name = sectionDraft.name.trim();
    const clientName = sectionDraft.scope === "client" ? sectionDraft.clientName.trim() : "";

    if (!name) {
      toast.error("Escribe el nombre de la sección.");
      return;
    }
    if (sectionDraft.scope === "client" && !clientName) {
      toast.error("Selecciona el cliente del tarifario especial.");
      return;
    }

    setSavingSection(true);
    try {
      const nextDraft = {
        ...sectionDraft,
        id:
          editingSection?.id ||
          buildTariffSectionId(sectionDraft.scope, name, sectionDraft.clientName),
        name,
        clientName,
        pricingMode: sectionDraft.scope === "client" ? "fixed_multi" : "guided",
      } satisfies SectionDraft;

      await saveTariffSection(nextDraft);
      setFilter(nextDraft.scope);
      setSelectedSectionId(nextDraft.id);
      setSectionEditorOpen(false);
      toast.success(editingSection ? "Sección actualizada." : "Sección creada.");
    } catch (error) {
      console.error("Error guardando sección del tarifario:", error);
      toast.error(error instanceof Error ? error.message : "No se pudo guardar la sección.");
    } finally {
      setSavingSection(false);
    }
  };

  const toggleSectionActive = async (section: TariffSection) => {
    setChangingActiveId(section.id);
    try {
      await setTariffSectionActive(section, !section.isActive);
      toast.success(section.isActive ? "Sección desactivada." : "Sección reactivada.");
    } catch (error) {
      console.error("Error cambiando estado de sección:", error);
      toast.error("No se pudo cambiar el estado de la sección.");
    } finally {
      setChangingActiveId(null);
    }
  };

  const openNewRow = () => {
    if (!selectedSection) return;
    setEditingRow(null);
    setRowDraft(blankRow(selectedSection, rows));
    setRowEditorOpen(true);
  };

  const openEditRow = (row: TariffCatalogRow) => {
    setEditingRow(row);
    setRowDraft(rowToDraft(row));
    setRowEditorOpen(true);
  };

  const saveRow = async () => {
    if (!rowDraft || !selectedSection) return;

    const isSpecial = selectedSection.scope === "client";
    const service = rowDraft.service.trim();
    const category = isSpecial ? selectedSection.name : rowDraft.category.trim();
    const notes = rowDraft.notes.trim();

    if (!service) {
      toast.error(isSpecial ? "Escribe el nombre de la pieza." : "Escribe el servicio o ítem.");
      return;
    }
    if (!isSpecial && !category) {
      toast.error("Escribe la categoría.");
      return;
    }

    const min = rowDraft.reference_min == null ? null : Number(rowDraft.reference_min);
    const max = rowDraft.reference_max == null ? null : Number(rowDraft.reference_max);

    if (isSpecial && (!Number.isFinite(min) || Number(min) <= 0)) {
      toast.error("El monto fijo debe ser mayor que cero.");
      return;
    }
    if (min != null && max != null && min > max) {
      toast.error("El monto mínimo no puede ser mayor que el máximo.");
      return;
    }

    setSavingRow(true);
    try {
      const matchingCatalogRow = !isSpecial
        ? rows.find(
            (candidate) =>
              candidate.section === selectedSection.id &&
              slugifyTariffValue(candidate.category) === slugifyTariffValue(category) &&
              slugifyTariffValue(candidate.service) === slugifyTariffValue(service),
          )
        : null;
      const catalogItemId =
        editingRow?.catalog_item_id ||
        matchingCatalogRow?.catalog_item_id ||
        slugifyTariffValue(`${selectedSection.id}-${category}-${service}`);
      const workTypeLabel = isSpecial
        ? "Tarifa fija"
        : rowDraft.work_type_label.trim() || "Referencia";
      const levelLabel = isSpecial ? "Precio fijo" : rowDraft.level_label.trim() || "Precio único";
      const workTypeId = editingRow?.work_type_id || slugifyTariffValue(workTypeLabel) || "reference";
      const levelId = editingRow?.level_id || slugifyTariffValue(levelLabel) || "project";
      const fixedAmount = isSpecial ? Number(min) : null;
      const nextRow: RowDraft = {
        ...rowDraft,
        id:
          editingRow?.id ||
          buildTariffRowId({
            catalog_item_id: catalogItemId,
            work_type_id: workTypeId,
            level_id: levelId,
          }),
        catalog_item_id: catalogItemId,
        section: selectedSection.id,
        category,
        service,
        notes,
        work_type_id: workTypeId,
        work_type_label: workTypeLabel,
        work_type_short_label: isSpecial
          ? "Fijo"
          : rowDraft.work_type_short_label.trim() || workTypeLabel,
        hour_reference: isSpecial ? "" : rowDraft.hour_reference.trim(),
        level_id: levelId,
        level_label: levelLabel,
        reference: isSpecial
          ? `${fixedAmount} USD`
          : rowDraft.reference.trim() || buildReference(min, max),
        reference_min: isSpecial ? fixedAmount : min,
        reference_max: isSpecial ? fixedAmount : max,
        level_hint: isSpecial ? "Monto fijo por pieza." : rowDraft.level_hint.trim(),
        sort_order: Number(rowDraft.sort_order || 0),
        is_active: rowDraft.is_active,
        managed_by: "app",
      };

      await saveTariffCatalogRow(nextRow, editingRow);
      setRowEditorOpen(false);
      toast.success(editingRow ? "Tarifa actualizada." : "Tarifa agregada.");
    } catch (error) {
      console.error("Error guardando tarifa:", error);
      toast.error(error instanceof Error ? error.message : "No se pudo guardar la tarifa.");
    } finally {
      setSavingRow(false);
    }
  };

  const toggleRowActive = async (row: TariffCatalogRow) => {
    setChangingActiveId(row.id);
    try {
      await setTariffCatalogRowActive(row, !row.is_active);
      toast.success(row.is_active ? "Tarifa desactivada." : "Tarifa reactivada.");
    } catch (error) {
      console.error("Error cambiando estado de tarifa:", error);
      toast.error("No se pudo cambiar el estado de la tarifa.");
    } finally {
      setChangingActiveId(null);
    }
  };

  const loading = sectionsLoading || rowsLoading;
  const error = sectionsError || rowsError;

  return (
    <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="h-[90vh] max-h-[900px] w-[96vw] max-w-[1280px] overflow-hidden p-0">
          <div className="flex h-full min-h-0 flex-col">
            <div className="border-b border-border px-6 py-5 pr-14">
              <DialogHeader>
                <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                  <div>
                    <DialogTitle className="flex items-center gap-2 text-xl">
                      <BadgeDollarSign className="h-5 w-5 text-primary" />
                      Administración del tarifario
                    </DialogTitle>
                    <DialogDescription className="mt-1 max-w-3xl">
                      Crea secciones generales, administra tarifas por cliente y edita los ítems que
                      ya utiliza el equipo al cotizar proyectos.
                    </DialogDescription>
                  </div>

                  <div className="flex flex-wrap gap-2">
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      className="gap-1.5"
                      onClick={() => void Promise.all([refreshSections(), refreshRows()])}
                      disabled={loading}
                    >
                      <RefreshCw className={cn("h-3.5 w-3.5", loading && "animate-spin")} />
                      Actualizar
                    </Button>
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      className="gap-1.5"
                      onClick={() => openNewSection("client")}
                    >
                      <Building2 className="h-3.5 w-3.5" />
                      Tarifario por cliente
                    </Button>
                    <Button
                      type="button"
                      size="sm"
                      className="gap-1.5"
                      onClick={() => openNewSection("general")}
                    >
                      <Plus className="h-3.5 w-3.5" />
                      Sección general
                    </Button>
                  </div>
                </div>
              </DialogHeader>

              <div className="mt-4 grid grid-cols-1 gap-2 sm:grid-cols-3">
                <SummaryCard
                  icon={<Layers3 className="h-4 w-4" />}
                  label="Secciones activas"
                  value={sections.filter((section) => section.isActive).length}
                />
                <SummaryCard
                  icon={<Building2 className="h-4 w-4" />}
                  label="Tarifarios por cliente"
                  value={totalSpecialSections}
                />
                <SummaryCard
                  icon={<CircleDollarSign className="h-4 w-4" />}
                  label="Tarifas activas"
                  value={totalActiveRows}
                />
              </div>
            </div>

            {error && (
              <div className="border-b border-amber-200 bg-amber-50 px-6 py-2 text-xs text-amber-900">
                {error}
              </div>
            )}

            <div className="grid min-h-0 flex-1 grid-cols-1 lg:grid-cols-[310px_minmax(0,1fr)]">
              <aside className="flex min-h-0 flex-col border-b border-border bg-muted/20 lg:border-b-0 lg:border-r">
                <div className="space-y-3 p-4">
                  <Tabs value={filter} onValueChange={(value) => setFilter(value as SectionFilter)}>
                    <TabsList className="grid w-full grid-cols-2">
                      <TabsTrigger value="general">Generales</TabsTrigger>
                      <TabsTrigger value="client">Por cliente</TabsTrigger>
                    </TabsList>
                  </Tabs>

                  <p className="text-xs text-muted-foreground">
                    {filter === "general"
                      ? "Estas secciones aparecen para los clientes que no tienen un tarifario especial."
                      : "Cada tarifario aparece únicamente al seleccionar el cliente asociado."}
                  </p>
                </div>

                <ScrollArea className="min-h-[220px] flex-1 px-3 pb-3">
                  <div className="space-y-2 pr-2">
                    {paginatedSections.map((section) => {
                      const selected = section.id === selectedSection?.id;
                      const itemCount = rows.filter(
                        (row) => row.section === section.id && row.is_active,
                      ).length;

                      return (
                        <button
                          type="button"
                          key={section.id}
                          onClick={() => setSelectedSectionId(section.id)}
                          className={cn(
                            "w-full rounded-xl border px-3 py-3 text-left transition-colors",
                            selected
                              ? "border-primary/40 bg-primary/10"
                              : "border-border bg-card hover:bg-muted/50",
                            !section.isActive && "opacity-60",
                          )}
                        >
                          <div className="flex items-start justify-between gap-2">
                            <div className="min-w-0">
                              <p className="truncate text-sm font-semibold">{section.name}</p>
                              {section.scope === "client" && (
                                <p className="mt-0.5 truncate text-xs text-muted-foreground">
                                  {section.clientName}
                                </p>
                              )}
                            </div>
                            <Badge variant={section.isActive ? "secondary" : "outline"}>
                              {section.isActive ? "Activa" : "Inactiva"}
                            </Badge>
                          </div>
                          <p className="mt-2 text-xs text-muted-foreground">
                            {itemCount} tarifa(s) activa(s)
                          </p>
                        </button>
                      );
                    })}

                    {filteredSections.length === 0 && (
                      <div className="rounded-xl border border-dashed border-border bg-card px-3 py-5 text-center text-sm text-muted-foreground">
                        No hay secciones de este tipo.
                      </div>
                    )}
                  </div>
                </ScrollArea>

                <PaginationBar
                  currentPage={sectionPage}
                  totalPages={sectionPageCount}
                  totalItems={filteredSections.length}
                  pageSize={SECTION_PAGE_SIZE}
                  itemLabel="secciones"
                  onPageChange={changeSectionPage}
                  compact
                />
              </aside>

              <section className="min-h-0">
                {!selectedSection ? (
                  <div className="flex h-full items-center justify-center p-8 text-center text-sm text-muted-foreground">
                    Selecciona o crea una sección para comenzar.
                  </div>
                ) : (
                  <div className="flex h-full min-h-0 flex-col">
                    <div className="border-b border-border px-5 py-4">
                      <div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
                        <div>
                          <div className="flex flex-wrap items-center gap-2">
                            <h3 className="text-lg font-semibold">{selectedSection.name}</h3>
                            <Badge variant={selectedSection.scope === "client" ? "default" : "secondary"}>
                              {selectedSection.scope === "client" ? "Por cliente" : "General"}
                            </Badge>
                            {!selectedSection.isActive && <Badge variant="outline">Inactiva</Badge>}
                          </div>
                          {selectedSection.scope === "client" && (
                            <p className="mt-1 text-sm text-primary">
                              Se muestra al seleccionar: {selectedSection.clientName}
                            </p>
                          )}
                          <p className="mt-1 max-w-3xl text-sm text-muted-foreground">
                            {selectedSection.description || "Sin descripción."}
                          </p>
                        </div>

                        <div className="flex flex-wrap gap-2">
                          <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            className="gap-1.5"
                            onClick={() => openEditSection(selectedSection)}
                          >
                            <Settings2 className="h-3.5 w-3.5" />
                            Editar sección
                          </Button>
                          <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            className="gap-1.5"
                            onClick={() => void toggleSectionActive(selectedSection)}
                            disabled={changingActiveId === selectedSection.id}
                          >
                            {selectedSection.isActive ? (
                              <ArchiveRestore className="h-3.5 w-3.5 rotate-180" />
                            ) : (
                              <ArchiveRestore className="h-3.5 w-3.5" />
                            )}
                            {selectedSection.isActive ? "Desactivar" : "Reactivar"}
                          </Button>
                          <Button
                            type="button"
                            size="sm"
                            className="gap-1.5"
                            onClick={openNewRow}
                          >
                            <Plus className="h-3.5 w-3.5" />
                            {selectedSection.scope === "client" ? "Nueva pieza" : "Nueva tarifa"}
                          </Button>
                        </div>
                      </div>
                    </div>

                    <div className="flex flex-wrap items-center gap-3 border-b border-border px-5 py-3">
                      <div className="relative min-w-[220px] flex-1">
                        <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                        <Input
                          value={search}
                          onChange={(event) => setSearch(event.target.value)}
                          className="pl-9"
                          placeholder="Buscar servicio, categoría o nivel…"
                        />
                      </div>
                      <label className="flex items-center gap-2 text-xs text-muted-foreground">
                        <Switch checked={showInactiveRows} onCheckedChange={setShowInactiveRows} />
                        Mostrar inactivas
                      </label>
                    </div>

                    <ScrollArea className="min-h-0 flex-1">
                      <div className="space-y-3 p-5">
                        {loading && selectedRows.length === 0 ? (
                          <div className="flex items-center justify-center gap-2 py-12 text-sm text-muted-foreground">
                            <Loader2 className="h-4 w-4 animate-spin" /> Cargando tarifario…
                          </div>
                        ) : selectedRows.length === 0 ? (
                          <div className="rounded-2xl border border-dashed border-border bg-muted/20 px-5 py-10 text-center">
                            <CircleDollarSign className="mx-auto h-8 w-8 text-muted-foreground" />
                            <p className="mt-3 text-sm font-medium">No hay tarifas para mostrar</p>
                            <p className="mt-1 text-xs text-muted-foreground">
                              Agrega la primera tarifa de esta sección o activa “Mostrar inactivas”.
                            </p>
                            <Button className="mt-4 gap-1.5" size="sm" onClick={openNewRow}>
                              <Plus className="h-3.5 w-3.5" /> Agregar tarifa
                            </Button>
                          </div>
                        ) : (
                          paginatedRows.map((row) => (
                            <TariffRowCard
                              key={row.id}
                              row={row}
                              section={selectedSection}
                              busy={changingActiveId === row.id}
                              onEdit={() => openEditRow(row)}
                              onToggle={() => void toggleRowActive(row)}
                            />
                          ))
                        )}
                      </div>
                    </ScrollArea>

                    <PaginationBar
                      currentPage={tariffPage}
                      totalPages={tariffPageCount}
                      totalItems={selectedRows.length}
                      pageSize={TARIFF_PAGE_SIZE}
                      itemLabel="tarifas"
                      onPageChange={setTariffPage}
                    />
                  </div>
                )}
              </section>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      <SectionEditorDialog
        open={sectionEditorOpen}
        onOpenChange={setSectionEditorOpen}
        draft={sectionDraft}
        onDraftChange={setSectionDraft}
        clients={lists.clientes}
        editing={Boolean(editingSection)}
        saving={savingSection}
        onSave={() => void saveSection()}
      />

      <RowEditorDialog
        open={rowEditorOpen}
        onOpenChange={setRowEditorOpen}
        section={selectedSection}
        draft={rowDraft}
        onDraftChange={setRowDraft}
        editing={Boolean(editingRow)}
        saving={savingRow}
        onSave={() => void saveRow()}
      />
    </>
  );
}

function PaginationBar({
  currentPage,
  totalPages,
  totalItems,
  pageSize,
  itemLabel,
  onPageChange,
  compact = false,
}: {
  currentPage: number;
  totalPages: number;
  totalItems: number;
  pageSize: number;
  itemLabel: string;
  onPageChange: (page: number) => void;
  compact?: boolean;
}) {
  const firstItem = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
  const lastItem = Math.min(currentPage * pageSize, totalItems);

  return (
    <div
      className={cn(
        "flex items-center justify-between gap-3 border-t border-border bg-background/95 px-4 py-2.5",
        compact && "px-3",
      )}
    >
      <p className="text-[11px] text-muted-foreground">
        {firstItem}–{lastItem} de {totalItems} {itemLabel}
      </p>
      <div className="flex items-center gap-1.5">
        {!compact && (
          <span className="mr-1 text-[11px] text-muted-foreground">
            Página {currentPage} de {totalPages}
          </span>
        )}
        <Button
          type="button"
          variant="outline"
          size="icon"
          className="h-7 w-7"
          aria-label="Página anterior"
          onClick={() => onPageChange(currentPage - 1)}
          disabled={currentPage <= 1}
        >
          <ChevronLeft className="h-3.5 w-3.5" />
        </Button>
        {compact && (
          <span className="min-w-[42px] text-center text-[11px] text-muted-foreground">
            {currentPage}/{totalPages}
          </span>
        )}
        <Button
          type="button"
          variant="outline"
          size="icon"
          className="h-7 w-7"
          aria-label="Página siguiente"
          onClick={() => onPageChange(currentPage + 1)}
          disabled={currentPage >= totalPages}
        >
          <ChevronRight className="h-3.5 w-3.5" />
        </Button>
      </div>
    </div>
  );
}

function SummaryCard({ icon, label, value }: { icon: ReactNode; label: string; value: number }) {
  return (
    <div className="flex items-center gap-3 rounded-xl border border-border bg-muted/20 px-3 py-2.5">
      <span className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 text-primary">
        {icon}
      </span>
      <div>
        <p className="text-lg font-semibold leading-none">{value}</p>
        <p className="mt-1 text-[11px] text-muted-foreground">{label}</p>
      </div>
    </div>
  );
}

function TariffRowCard({
  row,
  section,
  busy,
  onEdit,
  onToggle,
}: {
  row: TariffCatalogRow;
  section: TariffSection;
  busy: boolean;
  onEdit: () => void;
  onToggle: () => void;
}) {
  const isSpecial = section.scope === "client";
  const amountLabel = isSpecial
    ? formatMoney(row.reference_min ?? row.reference_max)
    : row.reference ||
      (row.reference_min != null || row.reference_max != null
        ? `${formatMoney(row.reference_min)} – ${formatMoney(row.reference_max)}`
        : "Sin monto de referencia");

  return (
    <div
      className={cn(
        "rounded-2xl border border-border bg-card px-4 py-3 shadow-sm",
        !row.is_active && "opacity-60",
      )}
    >
      <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-center gap-2">
            <p className="font-medium">{row.service}</p>
            <Badge variant={row.is_active ? "secondary" : "outline"}>
              {row.is_active ? "Activa" : "Inactiva"}
            </Badge>
            {row.managed_by === "app" && <Badge variant="outline">Gestionada en app</Badge>}
          </div>
          {!isSpecial && <p className="mt-1 text-sm text-muted-foreground">{row.category}</p>}
          <div className="mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground">
            {!isSpecial && <span>{row.work_type_label}</span>}
            {!isSpecial && <span>{row.level_label}</span>}
            <span className="font-semibold text-foreground">{amountLabel}</span>
            <span>Orden: {row.sort_order}</span>
          </div>
          {row.notes && <p className="mt-2 line-clamp-2 text-xs text-muted-foreground">{row.notes}</p>}
        </div>

        <div className="flex gap-2">
          <Button type="button" variant="outline" size="sm" className="gap-1.5" onClick={onEdit}>
            <Edit3 className="h-3.5 w-3.5" /> Editar
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            onClick={onToggle}
            disabled={busy}
          >
            {busy ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : row.is_active ? "Desactivar" : "Reactivar"}
          </Button>
        </div>
      </div>
    </div>
  );
}

function SectionEditorDialog({
  open,
  onOpenChange,
  draft,
  onDraftChange,
  clients,
  editing,
  saving,
  onSave,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  draft: SectionDraft | null;
  onDraftChange: (draft: SectionDraft | null) => void;
  clients: string[];
  editing: boolean;
  saving: boolean;
  onSave: () => void;
}) {
  if (!draft) return null;
  const isSpecial = draft.scope === "client";

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>{editing ? "Editar sección" : isSpecial ? "Nuevo tarifario por cliente" : "Nueva sección general"}</DialogTitle>
          <DialogDescription>
            {isSpecial
              ? "El tarifario aparecerá automáticamente cuando se seleccione el cliente indicado."
              : "La sección aparecerá junto a las demás secciones del tarifario general."}
          </DialogDescription>
        </DialogHeader>

        <div className="grid grid-cols-1 gap-4 py-2 sm:grid-cols-2">
          <div className="space-y-1.5 sm:col-span-2">
            <Label>Nombre de la sección</Label>
            <Input
              value={draft.name}
              onChange={(event) => onDraftChange({ ...draft, name: event.target.value })}
              placeholder={isSpecial ? "Ej: Tarifario PepsiCo" : "Ej: Producción audiovisual"}
            />
          </div>

          {isSpecial && (
            <div className="space-y-1.5 sm:col-span-2">
              <Label>Cliente asociado</Label>
              <SearchableSelect
                value={draft.clientName}
                options={clients}
                onValueChange={(clientName) => onDraftChange({ ...draft, clientName })}
                placeholder="Seleccionar cliente…"
                searchPlaceholder="Buscar cliente…"
                emptyText="No se encontró ese cliente en las listas de la app."
              />
              <p className="text-xs text-muted-foreground">
                El nombre debe coincidir con el cliente disponible en el formulario de proyectos.
              </p>
            </div>
          )}

          <div className="space-y-1.5 sm:col-span-2">
            <Label>Descripción para el usuario</Label>
            <Textarea
              value={draft.description}
              onChange={(event) => onDraftChange({ ...draft, description: event.target.value })}
              placeholder="Explica brevemente qué incluye esta sección."
              rows={3}
            />
          </div>

          <div className="space-y-1.5">
            <Label>Orden</Label>
            <Input
              type="number"
              min="0"
              value={draft.sortOrder}
              onChange={(event) =>
                onDraftChange({ ...draft, sortOrder: Number(event.target.value || 0) })
              }
            />
          </div>

          <div className="flex flex-col justify-end gap-3 rounded-xl border border-border bg-muted/20 px-3 py-2.5">
            <label className="flex items-center justify-between gap-3 text-sm">
              <span>Sección activa</span>
              <Switch
                checked={draft.isActive}
                onCheckedChange={(isActive) => onDraftChange({ ...draft, isActive })}
              />
            </label>
            {isSpecial && (
              <label className="flex items-center justify-between gap-3 text-sm">
                <span>Permitir costo manual</span>
                <Switch
                  checked={draft.allowManual}
                  onCheckedChange={(allowManual) => onDraftChange({ ...draft, allowManual })}
                />
              </label>
            )}
          </div>
        </div>

        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
            Cancelar
          </Button>
          <Button type="button" className="gap-1.5" onClick={onSave} disabled={saving}>
            {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Check className="h-4 w-4" />}
            Guardar sección
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function RowEditorDialog({
  open,
  onOpenChange,
  section,
  draft,
  onDraftChange,
  editing,
  saving,
  onSave,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  section: TariffSection | null;
  draft: RowDraft | null;
  onDraftChange: (draft: RowDraft | null) => void;
  editing: boolean;
  saving: boolean;
  onSave: () => void;
}) {
  if (!draft || !section) return null;
  const isSpecial = section.scope === "client";

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[88vh] max-w-3xl overflow-y-auto">
        <DialogHeader>
          <DialogTitle>
            {editing
              ? isSpecial
                ? "Editar pieza"
                : "Editar tarifa"
              : isSpecial
                ? "Nueva pieza de precio fijo"
                : "Nueva tarifa"}
          </DialogTitle>
          <DialogDescription>
            Sección: {section.name}
          </DialogDescription>
        </DialogHeader>

        {isSpecial ? (
          <div className="grid grid-cols-1 gap-4 py-2 sm:grid-cols-[minmax(0,1fr)_200px]">
            <div className="space-y-1.5">
              <Label>Nombre de la pieza</Label>
              <Input
                value={draft.service}
                onChange={(event) => onDraftChange({ ...draft, service: event.target.value })}
                placeholder="Ej: Photobooth"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Monto fijo (USD)</Label>
              <Input
                type="number"
                min="0"
                step="0.01"
                value={draft.reference_min ?? ""}
                onChange={(event) =>
                  onDraftChange({ ...draft, reference_min: numericValue(event.target.value) })
                }
                placeholder="0.00"
              />
            </div>
            <div className="space-y-1.5 sm:col-span-2">
              <Label>Descripción / incluye</Label>
              <Textarea
                value={draft.notes}
                onChange={(event) => onDraftChange({ ...draft, notes: event.target.value })}
                placeholder="Describe qué incluye esta pieza y cualquier observación importante."
                rows={4}
              />
            </div>
          </div>
        ) : (
          <div className="grid grid-cols-1 gap-4 py-2 sm:grid-cols-2">
            <div className="space-y-1.5">
              <Label>Categoría</Label>
              <Input
                value={draft.category}
                onChange={(event) => onDraftChange({ ...draft, category: event.target.value })}
                placeholder="Ej: Materiales de PDV"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Servicio / ítem</Label>
              <Input
                value={draft.service}
                onChange={(event) => onDraftChange({ ...draft, service: event.target.value })}
                placeholder="Ej: Diseño de roll up"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Tipo de trabajo</Label>
              <Input
                value={draft.work_type_label}
                onChange={(event) =>
                  onDraftChange({ ...draft, work_type_label: event.target.value })
                }
                placeholder="Ej: Diseño + Arte Final"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Etiqueta corta</Label>
              <Input
                value={draft.work_type_short_label}
                onChange={(event) =>
                  onDraftChange({ ...draft, work_type_short_label: event.target.value })
                }
                placeholder="Ej: Diseño"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Nivel / referencia</Label>
              <Input
                value={draft.level_label}
                onChange={(event) => onDraftChange({ ...draft, level_label: event.target.value })}
                placeholder="Ej: Básico"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Hora hombre ref.</Label>
              <Input
                value={draft.hour_reference}
                onChange={(event) =>
                  onDraftChange({ ...draft, hour_reference: event.target.value })
                }
                placeholder="Ej: 35 - 50"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Monto mínimo</Label>
              <Input
                type="number"
                min="0"
                step="0.01"
                value={draft.reference_min ?? ""}
                onChange={(event) =>
                  onDraftChange({ ...draft, reference_min: numericValue(event.target.value) })
                }
                placeholder="0.00"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Monto máximo</Label>
              <Input
                type="number"
                min="0"
                step="0.01"
                value={draft.reference_max ?? ""}
                onChange={(event) =>
                  onDraftChange({ ...draft, reference_max: numericValue(event.target.value) })
                }
                placeholder="0.00"
              />
            </div>
            <div className="space-y-1.5 sm:col-span-2">
              <Label>Referencia visible</Label>
              <Input
                value={draft.reference}
                onChange={(event) => onDraftChange({ ...draft, reference: event.target.value })}
                placeholder="Ej: 100 - 150 USD (se genera automáticamente si se deja vacío)"
              />
            </div>
            <div className="space-y-1.5 sm:col-span-2">
              <Label>Observaciones / incluye</Label>
              <Textarea
                value={draft.notes}
                onChange={(event) => onDraftChange({ ...draft, notes: event.target.value })}
                placeholder="Describe qué incluye el servicio."
                rows={3}
              />
            </div>
            <div className="space-y-1.5 sm:col-span-2">
              <Label>Nota del nivel</Label>
              <Textarea
                value={draft.level_hint}
                onChange={(event) => onDraftChange({ ...draft, level_hint: event.target.value })}
                placeholder="Ej: Puede superar el rango si la complejidad lo requiere."
                rows={2}
              />
            </div>
          </div>
        )}

        <Separator />
        <div className="grid grid-cols-1 gap-4 py-2 sm:grid-cols-2">
          <div className="space-y-1.5">
            <Label>Orden</Label>
            <Input
              type="number"
              min="0"
              value={draft.sort_order}
              onChange={(event) =>
                onDraftChange({ ...draft, sort_order: Number(event.target.value || 0) })
              }
            />
          </div>
          <label className="flex items-center justify-between gap-3 rounded-xl border border-border bg-muted/20 px-3 py-2.5 text-sm">
            <span>Tarifa activa</span>
            <Switch
              checked={draft.is_active}
              onCheckedChange={(is_active) => onDraftChange({ ...draft, is_active })}
            />
          </label>
        </div>

        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
            Cancelar
          </Button>
          <Button type="button" className="gap-1.5" onClick={onSave} disabled={saving}>
            {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Check className="h-4 w-4" />}
            Guardar tarifa
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
