import { useEffect, useState } from "react";

import { supabase } from "@/lib/supabase";

export type TariffSectionScope = "general" | "client";
export type TariffPricingMode = "guided" | "fixed_multi";

export type TariffSection = {
  id: string;
  name: string;
  scope: TariffSectionScope;
  clientName: string;
  pricingMode: TariffPricingMode;
  allowManual: boolean;
  description: string;
  sortOrder: number;
  isActive: boolean;
  createdAt?: string | null;
  updatedAt?: string | null;
};

export type TariffSectionInput = Omit<TariffSection, "createdAt" | "updatedAt">;

type TariffSectionRow = {
  id?: string | null;
  name?: string | null;
  scope?: string | null;
  client_name?: string | null;
  pricing_mode?: string | null;
  allow_manual?: boolean | null;
  description?: string | null;
  sort_order?: number | string | null;
  is_active?: boolean | null;
  created_at?: string | null;
  updated_at?: string | null;
};

type TariffSectionsState = {
  sections: TariffSection[];
  loading: boolean;
  error: string | null;
  source: "supabase" | "fallback";
};

const TABLE_NAME = "tablero_cdc_tariff_sections";

export const FALLBACK_TARIFF_SECTIONS: TariffSection[] = [
  {
    id: "grafico",
    name: "Tarifario Gráfico CDC",
    scope: "general",
    clientName: "",
    pricingMode: "guided",
    allowManual: true,
    description: "Diseño gráfico, artes finales, adaptaciones y materiales de punto de venta.",
    sortOrder: 10,
    isActive: true,
  },
  {
    id: "estrategia",
    name: "Estrategia y Creatividad",
    scope: "general",
    clientName: "",
    pricingMode: "guided",
    allowManual: true,
    description: "Servicios de estrategia, conceptualización y creatividad.",
    sortOrder: 20,
    isActive: true,
  },
  {
    id: "wmc",
    name: "Tarifario Walmart Connect",
    scope: "client",
    clientName: "Walmart Connect WMC",
    pricingMode: "fixed_multi",
    allowManual: true,
    description: "Piezas de precio fijo que aparecen únicamente para Walmart Connect WMC.",
    sortOrder: 100,
    isActive: true,
  },
];

let cache: TariffSectionsState = {
  sections: FALLBACK_TARIFF_SECTIONS,
  loading: false,
  error: null,
  source: "fallback",
};
let initialized = false;
let listeners: Array<() => void> = [];
let requestSequence = 0;

function notify() {
  listeners.forEach((listener) => listener());
}

export function slugifyTariffValue(value: string) {
  return String(value || "")
    .trim()
    .toLowerCase()
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 70);
}

export function buildTariffSectionId(scope: TariffSectionScope, name: string, clientName = "") {
  const base = slugifyTariffValue(scope === "client" ? clientName || name : name) || "seccion";
  const suffix = Date.now().toString(36).slice(-5);
  return `${scope === "client" ? "cliente" : "general"}-${base}-${suffix}`;
}

function normalizeRow(row: TariffSectionRow): TariffSection {
  const scope: TariffSectionScope = row.scope === "client" ? "client" : "general";
  const pricingMode: TariffPricingMode =
    row.pricing_mode === "fixed_multi" ? "fixed_multi" : "guided";

  return {
    id: String(row.id || "").trim(),
    name: String(row.name || "Sección sin nombre").trim(),
    scope,
    clientName: String(row.client_name || "").trim(),
    pricingMode,
    allowManual: row.allow_manual !== false,
    description: String(row.description || "").trim(),
    sortOrder: Number(row.sort_order || 0),
    isActive: row.is_active !== false,
    createdAt: row.created_at || null,
    updatedAt: row.updated_at || null,
  };
}

function missingTable(error: unknown) {
  const message = error instanceof Error ? error.message : String(error || "");
  return (
    message.includes(TABLE_NAME) ||
    message.includes("Could not find the table") ||
    message.includes("does not exist") ||
    message.includes("relation")
  );
}

export async function loadTariffSections(force = false): Promise<TariffSectionsState> {
  if (initialized && !force) return cache;

  const requestId = (requestSequence += 1);
  cache = { ...cache, loading: true, error: null };
  notify();

  try {
    const { data, error } = await supabase
      .from(TABLE_NAME)
      .select(
        "id, name, scope, client_name, pricing_mode, allow_manual, description, sort_order, is_active, created_at, updated_at",
      )
      .order("sort_order", { ascending: true })
      .order("name", { ascending: true });

    if (error) throw error;

    const dbSections = ((data || []) as TariffSectionRow[]).map(normalizeRow);
    const merged = new Map(FALLBACK_TARIFF_SECTIONS.map((section) => [section.id, section] as const));
    dbSections.forEach((section) => merged.set(section.id, section));

    const sections = Array.from(merged.values()).sort(
      (a, b) => a.sortOrder - b.sortOrder || a.name.localeCompare(b.name),
    );

    if (requestId === requestSequence) {
      cache = {
        sections,
        loading: false,
        error: dbSections.length
          ? null
          : "La tabla de secciones está vacía. Se muestran las secciones base como respaldo.",
        source: dbSections.length ? "supabase" : "fallback",
      };
      initialized = true;
      notify();
    }
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error || "");

    if (requestId === requestSequence) {
      cache = {
        sections: FALLBACK_TARIFF_SECTIONS,
        loading: false,
        error: missingTable(error)
          ? "Falta ejecutar el SQL del módulo de tarifario. Se muestran las secciones base como respaldo."
          : message || "No se pudieron cargar las secciones del tarifario.",
        source: "fallback",
      };
      initialized = true;
      notify();
    }
  }

  return cache;
}

export async function saveTariffSection(input: TariffSectionInput) {
  const cleanName = input.name.trim();
  const cleanClient = input.scope === "client" ? input.clientName.trim() : "";

  if (!cleanName) throw new Error("Escribe el nombre de la sección.");
  if (input.scope === "client" && !cleanClient) {
    throw new Error("Selecciona el cliente del tarifario especial.");
  }

  const { error } = await supabase.from(TABLE_NAME).upsert(
    {
      id: input.id,
      name: cleanName,
      scope: input.scope,
      client_name: cleanClient,
      pricing_mode: input.scope === "client" ? "fixed_multi" : "guided",
      allow_manual: input.allowManual,
      description: input.description.trim(),
      sort_order: Number(input.sortOrder || 0),
      is_active: input.isActive,
    },
    { onConflict: "id" },
  );

  if (error) throw error;

  initialized = false;
  return loadTariffSections(true);
}

export async function setTariffSectionActive(section: TariffSection, isActive: boolean) {
  const { error } = await supabase
    .from(TABLE_NAME)
    .update({ is_active: isActive })
    .eq("id", section.id);

  if (error) throw error;

  initialized = false;
  return loadTariffSections(true);
}

export function useTariffSections() {
  const [, force] = useState(0);

  useEffect(() => {
    const listener = () => force((value) => value + 1);
    listeners.push(listener);

    if (!initialized && !cache.loading) {
      void loadTariffSections();
    }

    return () => {
      listeners = listeners.filter((current) => current !== listener);
    };
  }, []);

  return {
    ...cache,
    refresh: loadTariffSections,
  };
}
