-- +goose Up
-- +goose StatementBegin

-- ─────────────────────────────────────────────────────────────────────────────
-- ARQUIVOS  (file storage metadata; actual bytes live in S3/R2)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE arquivos (
    id           UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id    UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    user_id      UUID        REFERENCES users(id) ON DELETE SET NULL,
    nome         TEXT        NOT NULL,
    mime_type    TEXT        NOT NULL,
    tamanho      BIGINT      NOT NULL DEFAULT 0,  -- bytes
    bucket       TEXT        NOT NULL,
    chave        TEXT        NOT NULL,            -- object storage key
    url_publica  TEXT,
    entidade     TEXT,                            -- e.g. 'pedido', 'cliente'
    entidade_id  UUID,
    criado_em    TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_arquivos_tenant_criado   ON arquivos (tenant_id, criado_em DESC);
CREATE INDEX idx_arquivos_entidade        ON arquivos (tenant_id, entidade, entidade_id);

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

-- ─────────────────────────────────────────────────────────────────────────────
-- PERMISSOES_USUARIO  (granular per-user overrides beyond role defaults)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE permissoes_usuario (
    id          UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id   UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    user_id     UUID        NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    recurso     TEXT        NOT NULL,   -- e.g. 'clientes', 'financeiro'
    acoes       TEXT[]      NOT NULL DEFAULT '{}', -- e.g. '{read,create}'
    negado      BOOLEAN     NOT NULL DEFAULT false, -- explicit deny
    criado_em   TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, user_id, recurso)
);

CREATE INDEX idx_permissoes_tenant_criado ON permissoes_usuario (tenant_id, criado_em DESC);
CREATE INDEX idx_permissoes_user          ON permissoes_usuario (tenant_id, user_id);

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

-- ─────────────────────────────────────────────────────────────────────────────
-- CLIENTES
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE clientes (
    id          UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id   UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    nome        TEXT        NOT NULL,
    email       CITEXT,
    telefone    TEXT,
    documento   TEXT,                -- CPF / CNPJ
    tipo        TEXT        NOT NULL DEFAULT 'pf' CHECK (tipo IN ('pf','pj')),
    endereco    JSONB       NOT NULL DEFAULT '{}',
    ativo       BOOLEAN     NOT NULL DEFAULT true,
    criado_em   TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_clientes_tenant_criado ON clientes (tenant_id, criado_em DESC);
CREATE INDEX idx_clientes_email         ON clientes (tenant_id, email);
CREATE INDEX idx_clientes_documento     ON clientes (tenant_id, documento);

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

CREATE TRIGGER trg_clientes_updated BEFORE UPDATE ON clientes
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ─────────────────────────────────────────────────────────────────────────────
-- PRODUTOS  (estoque)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE produtos (
    id               UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id        UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    sku              TEXT        NOT NULL,
    nome             TEXT        NOT NULL,
    descricao        TEXT        NOT NULL DEFAULT '',
    preco            NUMERIC(15,4) NOT NULL DEFAULT 0,
    custo            NUMERIC(15,4) NOT NULL DEFAULT 0,
    quantidade_atual INTEGER     NOT NULL DEFAULT 0,
    quantidade_min   INTEGER     NOT NULL DEFAULT 0,
    unidade          TEXT        NOT NULL DEFAULT 'un',
    categoria        TEXT,
    ativo            BOOLEAN     NOT NULL DEFAULT true,
    criado_em        TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em    TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, sku)
);

CREATE INDEX idx_produtos_tenant_criado ON produtos (tenant_id, criado_em DESC);
CREATE INDEX idx_produtos_sku           ON produtos (tenant_id, sku);
CREATE INDEX idx_produtos_estoque_baixo ON produtos (tenant_id)
    WHERE quantidade_atual <= quantidade_min AND ativo = true;

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

CREATE TRIGGER trg_produtos_updated BEFORE UPDATE ON produtos
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ─────────────────────────────────────────────────────────────────────────────
-- MOVIMENTOS_ESTOQUE
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE movimentos_estoque (
    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        TEXT        NOT NULL CHECK (tipo IN ('entrada','saida','ajuste')),
    quantidade  INTEGER     NOT NULL,
    motivo      TEXT        NOT NULL DEFAULT '',
    criado_em   TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_movimentos_tenant_criado ON movimentos_estoque (tenant_id, criado_em DESC);
CREATE INDEX idx_movimentos_produto       ON movimentos_estoque (tenant_id, produto_id);

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

-- ─────────────────────────────────────────────────────────────────────────────
-- PEDIDOS  (vendas)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE pedidos (
    id          UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id   UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    cliente_id  UUID        REFERENCES clientes(id) ON DELETE SET NULL,
    status      TEXT        NOT NULL DEFAULT 'aberto'
                            CHECK (status IN ('aberto','confirmado','producao','entregue','cancelado')),
    total       NUMERIC(15,4) NOT NULL DEFAULT 0,
    desconto    NUMERIC(15,4) NOT NULL DEFAULT 0,
    observacoes TEXT        NOT NULL DEFAULT '',
    criado_em   TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_pedidos_tenant_criado  ON pedidos (tenant_id, criado_em DESC);
CREATE INDEX idx_pedidos_status         ON pedidos (tenant_id, status);
CREATE INDEX idx_pedidos_cliente        ON pedidos (tenant_id, cliente_id);

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

CREATE TRIGGER trg_pedidos_updated BEFORE UPDATE ON pedidos
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ─────────────────────────────────────────────────────────────────────────────
-- PEDIDO_VERSOES  (versioning / snapshot of order at each state transition)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE pedido_versoes (
    id          UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id   UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    pedido_id   UUID        NOT NULL REFERENCES pedidos(id) ON DELETE CASCADE,
    versao      INTEGER     NOT NULL,
    status      TEXT        NOT NULL,
    snapshot    JSONB       NOT NULL DEFAULT '{}',
    alterado_por UUID       REFERENCES users(id) ON DELETE SET NULL,
    criado_em   TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tenant_id, pedido_id, versao)
);

CREATE INDEX idx_pedido_versoes_tenant_criado ON pedido_versoes (tenant_id, criado_em DESC);
CREATE INDEX idx_pedido_versoes_pedido        ON pedido_versoes (tenant_id, pedido_id);

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

-- ─────────────────────────────────────────────────────────────────────────────
-- LANCAMENTOS  (financeiro — contas a pagar/receber)
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE lancamentos (
    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 ('receita','despesa')),
    categoria   TEXT          NOT NULL DEFAULT 'outros',
    valor       NUMERIC(15,4) NOT NULL,
    descricao   TEXT          NOT NULL DEFAULT '',
    vencimento  DATE          NOT NULL DEFAULT CURRENT_DATE,
    pago        BOOLEAN       NOT NULL DEFAULT false,
    pago_em     TIMESTAMPTZ,
    referencia  TEXT,         -- e.g. pedido UUID
    criado_em   TIMESTAMPTZ   NOT NULL DEFAULT now(),
    atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_lancamentos_tenant_criado    ON lancamentos (tenant_id, criado_em DESC);
CREATE INDEX idx_lancamentos_vencimento       ON lancamentos (tenant_id, vencimento);
CREATE INDEX idx_lancamentos_tipo_pago        ON lancamentos (tenant_id, tipo, pago);

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

CREATE TRIGGER trg_lancamentos_updated BEFORE UPDATE ON lancamentos
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ─────────────────────────────────────────────────────────────────────────────
-- ORDENS_PRODUCAO
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE ordens_producao (
    id           UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id    UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    pedido_id    UUID        REFERENCES pedidos(id) ON DELETE SET NULL,
    produto_id   UUID        REFERENCES produtos(id) ON DELETE SET NULL,
    quantidade   INTEGER     NOT NULL DEFAULT 1,
    status       TEXT        NOT NULL DEFAULT 'pendente'
                             CHECK (status IN ('pendente','em_producao','pausado','concluido','cancelado')),
    prioridade   INTEGER     NOT NULL DEFAULT 5 CHECK (prioridade BETWEEN 1 AND 10),
    observacoes  TEXT        NOT NULL DEFAULT '',
    iniciado_em  TIMESTAMPTZ,
    concluido_em TIMESTAMPTZ,
    criado_em    TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_ordens_tenant_criado ON ordens_producao (tenant_id, criado_em DESC);
CREATE INDEX idx_ordens_status        ON ordens_producao (tenant_id, status);

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

CREATE TRIGGER trg_ordens_updated BEFORE UPDATE ON ordens_producao
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ─────────────────────────────────────────────────────────────────────────────
-- REGISTROS_PONTO
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE registros_ponto (
    id             UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id      UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    funcionario_id UUID        NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    tipo           TEXT        NOT NULL
                               CHECK (tipo IN ('entrada','saida','intervalo_ini','intervalo_fim')),
    latitude       NUMERIC(10,6),
    longitude      NUMERIC(10,6),
    ip             INET,
    criado_em      TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_ponto_tenant_criado     ON registros_ponto (tenant_id, criado_em DESC);
CREATE INDEX idx_ponto_funcionario_data  ON registros_ponto (tenant_id, funcionario_id, criado_em DESC);

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

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DROP TABLE IF EXISTS registros_ponto    CASCADE;
DROP TABLE IF EXISTS ordens_producao    CASCADE;
DROP TABLE IF EXISTS lancamentos        CASCADE;
DROP TABLE IF EXISTS pedido_versoes     CASCADE;
DROP TABLE IF EXISTS pedidos            CASCADE;
DROP TABLE IF EXISTS movimentos_estoque CASCADE;
DROP TABLE IF EXISTS produtos           CASCADE;
DROP TABLE IF EXISTS clientes           CASCADE;
DROP TABLE IF EXISTS permissoes_usuario CASCADE;
DROP TABLE IF EXISTS arquivos           CASCADE;
-- +goose StatementEnd
