-- +goose Up
-- +goose StatementBegin

-- ─────────────────────────────────────────────────────────────────────────────
-- CATEGORIAS DE ESTOQUE
-- Tipos: materia-prima | insumo | cor | fabricante | tecido | tipo_servico |
--        modelo_peca | acabamento
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS estoque_categorias (
    id           UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id    UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    tipo         TEXT        NOT NULL CHECK (tipo IN (
                                 'materia_prima','insumo','cor','fabricante',
                                 'tecido','tipo_servico','modelo_peca','acabamento'
                             )),
    nome         TEXT        NOT NULL,
    codigo_cor   TEXT,                          -- usado quando tipo = 'cor'
    hex_cor      TEXT,                          -- #RRGGBB quando tipo = 'cor'
    descricao    TEXT        NOT NULL DEFAULT '',
    ativo        BOOLEAN     NOT NULL DEFAULT true,
    criado_em    TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, tipo, nome)
);

CREATE INDEX IF NOT EXISTS idx_est_cat_tenant_tipo  ON estoque_categorias (tenant_id, tipo);
CREATE INDEX IF NOT EXISTS idx_est_cat_tenant_ativo ON estoque_categorias (tenant_id, ativo);

ALTER TABLE estoque_categorias ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON estoque_categorias
    USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

CREATE TRIGGER trg_est_cat_updated BEFORE UPDATE ON estoque_categorias
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ─────────────────────────────────────────────────────────────────────────────
-- AMPLIAR tabela produtos (mantém compatibilidade com colunas antigas)
-- ─────────────────────────────────────────────────────────────────────────────
ALTER TABLE produtos
    ADD COLUMN IF NOT EXISTS codigo_barras    TEXT        NOT NULL DEFAULT '',
    ADD COLUMN IF NOT EXISTS categoria_id    UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS tipo_estoque    TEXT        NOT NULL DEFAULT 'controlado'
                                             CHECK (tipo_estoque IN ('controlado','sem_controle')),
    -- Unidades disponíveis para esse produto
    ADD COLUMN IF NOT EXISTS unidade_venda   TEXT        NOT NULL DEFAULT 'un'
                                             CHECK (unidade_venda IN ('un','peca','cx','mt','kg','lt','par','dz')),
    -- Preços
    ADD COLUMN IF NOT EXISTS preco_varejo    NUMERIC(15,4) NOT NULL DEFAULT 0,
    ADD COLUMN IF NOT EXISTS preco_promocional NUMERIC(15,4) NOT NULL DEFAULT 0,
    ADD COLUMN IF NOT EXISTS preco_atacado   NUMERIC(15,4) NOT NULL DEFAULT 0,
    -- Grade de tamanhos/cores habilitada?
    ADD COLUMN IF NOT EXISTS usa_grade       BOOLEAN     NOT NULL DEFAULT false,
    -- Relacionamento com categorias especiais
    ADD COLUMN IF NOT EXISTS fabricante_id   UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS tecido_id       UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS modelo_peca_id  UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL;

-- Índice para código de barras
CREATE UNIQUE INDEX IF NOT EXISTS idx_produtos_codbarras
    ON produtos (tenant_id, codigo_barras)
    WHERE codigo_barras <> '';

-- ─────────────────────────────────────────────────────────────────────────────
-- GRADE DE TAMANHOS (configuração por produto)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS produto_grade_tamanhos (
    id           UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id    UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    produto_id   UUID        NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
    tamanho      TEXT        NOT NULL,   -- PP, P, M, G, GG, XGG, 34, 36, 38 …
    ordem        INTEGER     NOT NULL DEFAULT 0,
    ativo        BOOLEAN     NOT NULL DEFAULT true,
    criado_em    TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, produto_id, tamanho)
);

CREATE INDEX IF NOT EXISTS idx_grade_tam_produto ON produto_grade_tamanhos (tenant_id, produto_id);

ALTER TABLE produto_grade_tamanhos ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON produto_grade_tamanhos
    USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

-- ─────────────────────────────────────────────────────────────────────────────
-- GRADE DE CORES (configuração por produto — referencia categoria 'cor')
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS produto_grade_cores (
    id           UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id    UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    produto_id   UUID        NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
    cor_id       UUID        NOT NULL REFERENCES estoque_categorias(id) ON DELETE CASCADE,
    ativo        BOOLEAN     NOT NULL DEFAULT true,
    criado_em    TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, produto_id, cor_id)
);

CREATE INDEX IF NOT EXISTS idx_grade_cor_produto ON produto_grade_cores (tenant_id, produto_id);

ALTER TABLE produto_grade_cores ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON produto_grade_cores
    USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

-- ─────────────────────────────────────────────────────────────────────────────
-- ESTOQUE POR COR + TAMANHO (saldo individual por variante)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS produto_estoque_grade (
    id              UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id       UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    produto_id      UUID        NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
    cor_id          UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    tamanho         TEXT        NOT NULL DEFAULT '',
    quantidade_atual INTEGER    NOT NULL DEFAULT 0,
    quantidade_min   INTEGER    NOT NULL DEFAULT 0,
    criado_em        TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em    TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, produto_id, cor_id, tamanho)
);

CREATE INDEX IF NOT EXISTS idx_est_grade_produto ON produto_estoque_grade (tenant_id, produto_id);
CREATE INDEX IF NOT EXISTS idx_est_grade_baixo   ON produto_estoque_grade (tenant_id)
    WHERE quantidade_atual <= quantidade_min;

ALTER TABLE produto_estoque_grade ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON produto_estoque_grade
    USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

CREATE TRIGGER trg_est_grade_updated BEFORE UPDATE ON produto_estoque_grade
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ─────────────────────────────────────────────────────────────────────────────
-- AMPLIAR movimentos_estoque
-- Adiciona: origem (materia_prima | insumo | produto), cor/tamanho, referência
-- ─────────────────────────────────────────────────────────────────────────────
ALTER TABLE movimentos_estoque
    ADD COLUMN IF NOT EXISTS origem         TEXT        NOT NULL DEFAULT 'produto'
                                            CHECK (origem IN ('produto','materia_prima','insumo')),
    ADD COLUMN IF NOT EXISTS cor_id         UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS tamanho        TEXT        NOT NULL DEFAULT '',
    ADD COLUMN IF NOT EXISTS preco_custo    NUMERIC(15,4) NOT NULL DEFAULT 0,
    ADD COLUMN IF NOT EXISTS referencia     TEXT        NOT NULL DEFAULT '',   -- ex: nº NF, pedido
    ADD COLUMN IF NOT EXISTS usuario_id     UUID        REFERENCES users(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS observacoes    TEXT        NOT NULL DEFAULT '';

-- ─────────────────────────────────────────────────────────────────────────────
-- MATÉRIA-PRIMA (tabela dedicada com campos específicos)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS materias_primas (
    id               UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id        UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    produto_id       UUID        NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
    fabricante_id    UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    tecido_id        UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    composicao       TEXT        NOT NULL DEFAULT '',   -- ex: 100% algodão
    gramatura        NUMERIC(8,2),                      -- g/m²
    largura_cm       NUMERIC(8,2),                      -- cm
    cor_id           UUID        REFERENCES estoque_categorias(id) ON DELETE SET NULL,
    lote             TEXT        NOT NULL DEFAULT '',
    criado_em        TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, produto_id)
);

CREATE INDEX IF NOT EXISTS idx_mp_tenant ON materias_primas (tenant_id);

ALTER TABLE materias_primas ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON materias_primas
    USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

-- ─────────────────────────────────────────────────────────────────────────────
-- INSUMOS (tabela dedicada)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS insumos (
    id            UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id     UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    produto_id    UUID        NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
    tipo_insumo   TEXT        NOT NULL DEFAULT '',   -- ex: linha, botão, zíper…
    fornecedor    TEXT        NOT NULL DEFAULT '',
    referencia    TEXT        NOT NULL DEFAULT '',
    criado_em     TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, produto_id)
);

CREATE INDEX IF NOT EXISTS idx_insumos_tenant ON insumos (tenant_id);

ALTER TABLE insumos ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON insumos
    USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DROP TABLE IF EXISTS insumos                  CASCADE;
DROP TABLE IF EXISTS materias_primas          CASCADE;
DROP TABLE IF EXISTS produto_estoque_grade    CASCADE;
DROP TABLE IF EXISTS produto_grade_cores      CASCADE;
DROP TABLE IF EXISTS produto_grade_tamanhos   CASCADE;

ALTER TABLE movimentos_estoque
    DROP COLUMN IF EXISTS origem,
    DROP COLUMN IF EXISTS cor_id,
    DROP COLUMN IF EXISTS tamanho,
    DROP COLUMN IF EXISTS preco_custo,
    DROP COLUMN IF EXISTS referencia,
    DROP COLUMN IF EXISTS usuario_id,
    DROP COLUMN IF EXISTS observacoes;

ALTER TABLE produtos
    DROP COLUMN IF EXISTS codigo_barras,
    DROP COLUMN IF EXISTS categoria_id,
    DROP COLUMN IF EXISTS tipo_estoque,
    DROP COLUMN IF EXISTS unidade_venda,
    DROP COLUMN IF EXISTS preco_varejo,
    DROP COLUMN IF EXISTS preco_promocional,
    DROP COLUMN IF EXISTS preco_atacado,
    DROP COLUMN IF EXISTS usa_grade,
    DROP COLUMN IF EXISTS fabricante_id,
    DROP COLUMN IF EXISTS tecido_id,
    DROP COLUMN IF EXISTS modelo_peca_id;

DROP TABLE IF EXISTS estoque_categorias CASCADE;
-- +goose StatementEnd
