-- =============================================================================
-- Migration: 20260417000001_dev_tables
-- Área de Desenvolvimento (dev_*) — roadmap, auditoria, concorrentes, logs
-- -----------------------------------------------------------------------------
-- Tabelas usadas pela página /saas/desenvolvimento. Todas restritas a
-- saas_admins via RLS (helper public.is_saas_admin()).
-- =============================================================================

-- -----------------------------------------------------------------------------
-- Helper trigger: updated_at
-- -----------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION public.dev_set_updated_at()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
  NEW.updated_at := now();
  RETURN NEW;
END;
$$;

-- =============================================================================
-- 1. dev_roadmap_phases — Fases (1, 2, 3...)
-- =============================================================================
CREATE TABLE IF NOT EXISTS public.dev_roadmap_phases (
  id                 BIGSERIAL PRIMARY KEY,
  numero             INTEGER     NOT NULL UNIQUE,
  nome               VARCHAR(160) NOT NULL,
  objetivo           TEXT,
  timeline_sugerida  VARCHAR(160),
  criterio_saida     TEXT,
  status             VARCHAR(20) NOT NULL DEFAULT 'planejada'
                       CHECK (status IN ('planejada','em_andamento','concluida','arquivada')),
  data_inicio        DATE,
  data_fim           DATE,
  ordem              INTEGER     NOT NULL DEFAULT 0,
  created_at         TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at         TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_dev_roadmap_phases_status ON public.dev_roadmap_phases(status);
CREATE INDEX IF NOT EXISTS idx_dev_roadmap_phases_ordem  ON public.dev_roadmap_phases(ordem);

DROP TRIGGER IF EXISTS trg_dev_roadmap_phases_updated_at ON public.dev_roadmap_phases;
CREATE TRIGGER trg_dev_roadmap_phases_updated_at
  BEFORE UPDATE ON public.dev_roadmap_phases
  FOR EACH ROW EXECUTE FUNCTION public.dev_set_updated_at();

-- =============================================================================
-- 2. dev_roadmap_items — Itens das fases
-- =============================================================================
CREATE TABLE IF NOT EXISTS public.dev_roadmap_items (
  id             BIGSERIAL PRIMARY KEY,
  phase_id       BIGINT      NOT NULL REFERENCES public.dev_roadmap_phases(id) ON DELETE CASCADE,
  numero         INTEGER,
  bloco          VARCHAR(160),
  feature        TEXT        NOT NULL,
  descricao      TEXT,
  esforco        VARCHAR(4)
                   CHECK (esforco IS NULL OR esforco IN ('S','M','L','XL')),
  prioridade     VARCHAR(20)
                   CHECK (prioridade IS NULL OR prioridade IN ('bloqueador','alta','media','diferencial')),
  status         VARCHAR(20) NOT NULL DEFAULT 'pendente'
                   CHECK (status IN ('pendente','em_andamento','concluido','cancelado','bloqueado')),
  notas          TEXT,
  assignee       VARCHAR(120),
  data_inicio    DATE,
  data_conclusao DATE,
  ordem          INTEGER     NOT NULL DEFAULT 0,
  tags           TEXT[]      DEFAULT '{}',
  created_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at     TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_dev_roadmap_items_phase    ON public.dev_roadmap_items(phase_id);
CREATE INDEX IF NOT EXISTS idx_dev_roadmap_items_status   ON public.dev_roadmap_items(status);
CREATE INDEX IF NOT EXISTS idx_dev_roadmap_items_prior    ON public.dev_roadmap_items(prioridade);
CREATE INDEX IF NOT EXISTS idx_dev_roadmap_items_ordem    ON public.dev_roadmap_items(phase_id, ordem);

DROP TRIGGER IF EXISTS trg_dev_roadmap_items_updated_at ON public.dev_roadmap_items;
CREATE TRIGGER trg_dev_roadmap_items_updated_at
  BEFORE UPDATE ON public.dev_roadmap_items
  FOR EACH ROW EXECUTE FUNCTION public.dev_set_updated_at();

-- =============================================================================
-- 3. dev_auditoria_items — Bugs / débitos técnicos / decisões
-- =============================================================================
CREATE TABLE IF NOT EXISTS public.dev_auditoria_items (
  id                 BIGSERIAL PRIMARY KEY,
  categoria          VARCHAR(120),
  titulo             TEXT        NOT NULL,
  descricao_problema TEXT,
  solucao            TEXT,
  severidade         VARCHAR(20)
                       CHECK (severidade IS NULL OR severidade IN ('critico','alto','medio','baixo')),
  status             VARCHAR(20) NOT NULL DEFAULT 'aberto'
                       CHECK (status IN ('aberto','em_analise','resolvido','wontfix','duplicado')),
  resolvido_em       DATE,
  sessao_resolucao   VARCHAR(160),
  arquivo_afetado    TEXT,
  tags               TEXT[]      DEFAULT '{}',
  created_at         TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at         TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_dev_auditoria_items_status     ON public.dev_auditoria_items(status);
CREATE INDEX IF NOT EXISTS idx_dev_auditoria_items_severidade ON public.dev_auditoria_items(severidade);
CREATE INDEX IF NOT EXISTS idx_dev_auditoria_items_categoria  ON public.dev_auditoria_items(categoria);

DROP TRIGGER IF EXISTS trg_dev_auditoria_items_updated_at ON public.dev_auditoria_items;
CREATE TRIGGER trg_dev_auditoria_items_updated_at
  BEFORE UPDATE ON public.dev_auditoria_items
  FOR EACH ROW EXECUTE FUNCTION public.dev_set_updated_at();

-- =============================================================================
-- 4. dev_competitors — Concorrentes
-- =============================================================================
CREATE TABLE IF NOT EXISTS public.dev_competitors (
  id               BIGSERIAL PRIMARY KEY,
  slug             VARCHAR(80)  NOT NULL UNIQUE,
  nome             VARCHAR(160) NOT NULL,
  pais             VARCHAR(40),
  foco             VARCHAR(160),
  pricing          TEXT,
  posicionamento   TEXT,
  url              TEXT,
  ultima_pesquisa  DATE,
  notas            TEXT,
  ativo            BOOLEAN      NOT NULL DEFAULT true,
  ordem            INTEGER      NOT NULL DEFAULT 0,
  created_at       TIMESTAMPTZ  NOT NULL DEFAULT now(),
  updated_at       TIMESTAMPTZ  NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_dev_competitors_ativo ON public.dev_competitors(ativo);
CREATE INDEX IF NOT EXISTS idx_dev_competitors_pais  ON public.dev_competitors(pais);

DROP TRIGGER IF EXISTS trg_dev_competitors_updated_at ON public.dev_competitors;
CREATE TRIGGER trg_dev_competitors_updated_at
  BEFORE UPDATE ON public.dev_competitors
  FOR EACH ROW EXECUTE FUNCTION public.dev_set_updated_at();

-- =============================================================================
-- 5. dev_competitor_features — features de cada concorrente
-- =============================================================================
CREATE TABLE IF NOT EXISTS public.dev_competitor_features (
  id             BIGSERIAL PRIMARY KEY,
  competitor_id  BIGINT       NOT NULL REFERENCES public.dev_competitors(id) ON DELETE CASCADE,
  categoria      VARCHAR(120),
  nome           TEXT         NOT NULL,
  descricao      TEXT,
  fonte          VARCHAR(20)  NOT NULL DEFAULT 'publico'
                   CHECK (fonte IN ('fetched','observacao','publico','hipotese')),
  fonte_url      TEXT,
  data_fonte     DATE,
  destaque       BOOLEAN      NOT NULL DEFAULT false,
  created_at     TIMESTAMPTZ  NOT NULL DEFAULT now(),
  updated_at     TIMESTAMPTZ  NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_dev_competitor_features_comp     ON public.dev_competitor_features(competitor_id);
CREATE INDEX IF NOT EXISTS idx_dev_competitor_features_cat      ON public.dev_competitor_features(categoria);
CREATE INDEX IF NOT EXISTS idx_dev_competitor_features_destaque ON public.dev_competitor_features(destaque);

DROP TRIGGER IF EXISTS trg_dev_competitor_features_updated_at ON public.dev_competitor_features;
CREATE TRIGGER trg_dev_competitor_features_updated_at
  BEFORE UPDATE ON public.dev_competitor_features
  FOR EACH ROW EXECUTE FUNCTION public.dev_set_updated_at();

-- =============================================================================
-- 6. dev_comparison_matrix — AgenciaPsi × features-de-concorrente
-- =============================================================================
CREATE TABLE IF NOT EXISTS public.dev_comparison_matrix (
  id             BIGSERIAL PRIMARY KEY,
  dominio        VARCHAR(120),
  feature        TEXT         NOT NULL,
  nosso_status   VARCHAR(20)  NOT NULL DEFAULT 'a_definir'
                   CHECK (nosso_status IN ('tem','parcial','gap','na','a_definir')),
  nossa_nota     TEXT,
  importancia    VARCHAR(20)
                   CHECK (importancia IS NULL OR importancia IN ('alta','media','baixa')),
  ordem          INTEGER      NOT NULL DEFAULT 0,
  created_at     TIMESTAMPTZ  NOT NULL DEFAULT now(),
  updated_at     TIMESTAMPTZ  NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_dev_comparison_matrix_dominio  ON public.dev_comparison_matrix(dominio);
CREATE INDEX IF NOT EXISTS idx_dev_comparison_matrix_status   ON public.dev_comparison_matrix(nosso_status);

DROP TRIGGER IF EXISTS trg_dev_comparison_matrix_updated_at ON public.dev_comparison_matrix;
CREATE TRIGGER trg_dev_comparison_matrix_updated_at
  BEFORE UPDATE ON public.dev_comparison_matrix
  FOR EACH ROW EXECUTE FUNCTION public.dev_set_updated_at();

-- dev_comparison_competitor_status — opcional: status por concorrente por feature
-- (se quisermos marcar que competitor X tem feature Y). Tabela ponte N-N.
CREATE TABLE IF NOT EXISTS public.dev_comparison_competitor_status (
  id             BIGSERIAL PRIMARY KEY,
  comparison_id  BIGINT       NOT NULL REFERENCES public.dev_comparison_matrix(id) ON DELETE CASCADE,
  competitor_id  BIGINT       NOT NULL REFERENCES public.dev_competitors(id)        ON DELETE CASCADE,
  status         VARCHAR(20)  NOT NULL DEFAULT 'a_definir'
                   CHECK (status IN ('tem','parcial','gap','na','a_definir')),
  nota           TEXT,
  fonte          VARCHAR(20)
                   CHECK (fonte IS NULL OR fonte IN ('fetched','observacao','publico','hipotese')),
  created_at     TIMESTAMPTZ  NOT NULL DEFAULT now(),
  updated_at     TIMESTAMPTZ  NOT NULL DEFAULT now(),
  UNIQUE (comparison_id, competitor_id)
);
CREATE INDEX IF NOT EXISTS idx_dev_ccs_comp       ON public.dev_comparison_competitor_status(competitor_id);
CREATE INDEX IF NOT EXISTS idx_dev_ccs_comparison ON public.dev_comparison_competitor_status(comparison_id);

DROP TRIGGER IF EXISTS trg_dev_ccs_updated_at ON public.dev_comparison_competitor_status;
CREATE TRIGGER trg_dev_ccs_updated_at
  BEFORE UPDATE ON public.dev_comparison_competitor_status
  FOR EACH ROW EXECUTE FUNCTION public.dev_set_updated_at();

-- =============================================================================
-- 7. dev_generation_log — histórico de execuções (backup, dashboard, export...)
-- =============================================================================
CREATE TABLE IF NOT EXISTS public.dev_generation_log (
  id               BIGSERIAL PRIMARY KEY,
  tipo             VARCHAR(40)  NOT NULL,
  comando          TEXT,
  sucesso          BOOLEAN      NOT NULL DEFAULT false,
  stdout           TEXT,
  stderr           TEXT,
  duration_ms      INTEGER,
  metadata         JSONB        DEFAULT '{}'::jsonb,
  trigger_user_id  UUID,
  created_at       TIMESTAMPTZ  NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_dev_generation_log_tipo ON public.dev_generation_log(tipo);
CREATE INDEX IF NOT EXISTS idx_dev_generation_log_created ON public.dev_generation_log(created_at DESC);

-- =============================================================================
-- RLS — tudo restrito a saas_admins (helper existente: public.is_saas_admin())
-- =============================================================================
DO $$
DECLARE
  t TEXT;
  dev_tables TEXT[] := ARRAY[
    'dev_roadmap_phases',
    'dev_roadmap_items',
    'dev_auditoria_items',
    'dev_competitors',
    'dev_competitor_features',
    'dev_comparison_matrix',
    'dev_comparison_competitor_status',
    'dev_generation_log'
  ];
BEGIN
  FOREACH t IN ARRAY dev_tables
  LOOP
    EXECUTE format('ALTER TABLE public.%I ENABLE ROW LEVEL SECURITY;', t);

    -- Drop policy se existir (idempotente)
    EXECUTE format('DROP POLICY IF EXISTS %I ON public.%I;', t || '_saas_admin_all', t);

    -- Cria policy que permite tudo pra saas_admin
    EXECUTE format(
      'CREATE POLICY %I ON public.%I FOR ALL TO authenticated
         USING (public.is_saas_admin())
         WITH CHECK (public.is_saas_admin());',
      t || '_saas_admin_all',
      t
    );
  END LOOP;
END $$;

-- =============================================================================
-- Comentários
-- =============================================================================
COMMENT ON TABLE public.dev_roadmap_phases IS 'Fases do roadmap (MVP, Paridade, Diferenciação). Visível só pra saas_admins.';
COMMENT ON TABLE public.dev_roadmap_items IS 'Itens de cada fase do roadmap.';
COMMENT ON TABLE public.dev_auditoria_items IS 'Bugs, dívidas técnicas e decisões arquiteturais.';
COMMENT ON TABLE public.dev_competitors IS 'Concorrentes analisados no benchmark.';
COMMENT ON TABLE public.dev_competitor_features IS 'Features catalogadas de cada concorrente.';
COMMENT ON TABLE public.dev_comparison_matrix IS 'Matriz de comparação AgenciaPsi × features esperadas do mercado.';
COMMENT ON TABLE public.dev_comparison_competitor_status IS 'Qual concorrente tem qual feature (ponte N-N com matrix).';
COMMENT ON TABLE public.dev_generation_log IS 'Histórico de execuções (backup, dashboard, export, seed, etc).';
