-- =============================================================================
-- F1.1 — Schema-per-tenant: coluna tenants.slug
-- Plano: novo-rumo.txt + docs/F0_categorizacao.md (decisão Q1)
-- Slug é a base do nome do schema físico: tenant_<slug>. Unico e imutável.
-- =============================================================================

BEGIN;

ALTER TABLE public.tenants ADD COLUMN IF NOT EXISTS slug text;

-- Geração de slug a partir do nome (sanitizado pra identificador Postgres)
CREATE OR REPLACE FUNCTION public.generate_tenant_slug(p_name text)
RETURNS text
LANGUAGE plpgsql
STABLE
SECURITY DEFINER
SET search_path TO 'public', 'pg_temp'
AS $$
DECLARE
    base text;
    cand text;
    n int := 1;
BEGIN
    base := lower(coalesce(nullif(trim(p_name), ''), 'tenant'));
    base := translate(base,
        'áàâãäåéèêëíìîïóòôõöúùûüçñýÿ',
        'aaaaaaeeeeiiiiooooouuuucnyy');
    base := regexp_replace(base, '[^a-z0-9]+', '_', 'g');
    base := regexp_replace(base, '^_+|_+$', '', 'g');
    base := left(base, 48);
    IF base = '' OR base !~ '^[a-z]' THEN
        base := 't_' || base;
        base := left(base, 48);
    END IF;
    cand := base;
    WHILE EXISTS (SELECT 1 FROM public.tenants WHERE slug = cand) LOOP
        n := n + 1;
        cand := left(base, 44) || '_' || n;
    END LOOP;
    RETURN cand;
END;
$$;

-- Backfill dos tenants existentes
DO $$
DECLARE r record;
BEGIN
    FOR r IN SELECT id, name FROM public.tenants WHERE slug IS NULL ORDER BY created_at, id LOOP
        UPDATE public.tenants SET slug = public.generate_tenant_slug(r.name) WHERE id = r.id;
        RAISE NOTICE 'tenant % -> slug %', r.id, (SELECT slug FROM public.tenants WHERE id = r.id);
    END LOOP;
END $$;

ALTER TABLE public.tenants ALTER COLUMN slug SET NOT NULL;
ALTER TABLE public.tenants ADD CONSTRAINT tenants_slug_key UNIQUE (slug);
ALTER TABLE public.tenants ADD CONSTRAINT tenants_slug_format CHECK (slug ~ '^[a-z][a-z0-9_]{1,47}$');

-- Auto-gera no INSERT (provisionamento atual não conhece slug); imutável no UPDATE
CREATE OR REPLACE FUNCTION public.trg_tenants_slug()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path TO 'public', 'pg_temp'
AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        IF NEW.slug IS NULL OR trim(NEW.slug) = '' THEN
            NEW.slug := public.generate_tenant_slug(NEW.name);
        END IF;
        RETURN NEW;
    END IF;
    IF NEW.slug IS DISTINCT FROM OLD.slug THEN
        RAISE EXCEPTION 'tenants.slug é imutável (tenant %, % -> %)', OLD.id, OLD.slug, NEW.slug;
    END IF;
    RETURN NEW;
END;
$$;

DROP TRIGGER IF EXISTS trg_tenants_slug_ins ON public.tenants;
CREATE TRIGGER trg_tenants_slug_ins BEFORE INSERT ON public.tenants
    FOR EACH ROW EXECUTE FUNCTION public.trg_tenants_slug();

DROP TRIGGER IF EXISTS trg_tenants_slug_upd ON public.tenants;
CREATE TRIGGER trg_tenants_slug_upd BEFORE UPDATE OF slug ON public.tenants
    FOR EACH ROW EXECUTE FUNCTION public.trg_tenants_slug();

COMMIT;
