-- +goose Up
-- +goose StatementBegin

-- ─────────────────────────────────────────────────────────────────────────────
-- Registros de ponto
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS 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,7),
    longitude       NUMERIC(10,7),
    ip              TEXT        NOT NULL DEFAULT '',
    criado_em       TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_rp_tenant_func
    ON registros_ponto (tenant_id, funcionario_id, criado_em);

-- ─────────────────────────────────────────────────────────────────────────────
-- Jornadas de trabalho
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS jornadas (
    id                  UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id           UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    nome                TEXT        NOT NULL,
    descricao           TEXT        NOT NULL DEFAULT '',
    tipo                TEXT        NOT NULL DEFAULT 'fixo'
                                    CHECK (tipo IN ('fixo','turno','flex')),
    entrada             TIME,
    saida               TIME,
    intervalo_ini       TIME,
    intervalo_fim       TIME,
    horas_semanais      NUMERIC(5,2) NOT NULL DEFAULT 44,
    dias_semana         INT[]        NOT NULL DEFAULT '{1,2,3,4,5}',
    tolerancia_entrada  INT         NOT NULL DEFAULT 5,
    tolerancia_saida    INT         NOT NULL DEFAULT 5,
    adicional_noturno   BOOLEAN     NOT NULL DEFAULT false,
    perc_noturno        NUMERIC(5,2) NOT NULL DEFAULT 20,
    perc_he_50          NUMERIC(5,2) NOT NULL DEFAULT 50,
    perc_he_100         NUMERIC(5,2) NOT NULL DEFAULT 100,
    ativo               BOOLEAN     NOT NULL DEFAULT true,
    criado_em           TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em       TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_jornadas_tenant ON jornadas (tenant_id);

-- ─────────────────────────────────────────────────────────────────────────────
-- Vínculo funcionário ↔ jornada
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS funcionario_jornadas (
    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,
    jornada_id      UUID    NOT NULL REFERENCES jornadas(id) ON DELETE CASCADE,
    vigencia_ini    DATE    NOT NULL DEFAULT CURRENT_DATE,
    vigencia_fim    DATE,
    criado_em       TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_fj_tenant_func
    ON funcionario_jornadas (tenant_id, funcionario_id);

-- ─────────────────────────────────────────────────────────────────────────────
-- Banco de horas
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS banco_horas (
    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,
    data            DATE    NOT NULL,
    tipo            TEXT    NOT NULL
                            CHECK (tipo IN ('credito','debito','ajuste_manual','compensacao')),
    minutos         INT     NOT NULL,
    motivo          TEXT    NOT NULL DEFAULT '',
    aprovado_por    UUID    REFERENCES users(id) ON DELETE SET NULL,
    aprovado_em     TIMESTAMPTZ,
    criado_em       TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_bh_tenant_func_data
    ON banco_horas (tenant_id, funcionario_id, data);

-- ─────────────────────────────────────────────────────────────────────────────
-- Férias
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS ferias (
    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,
    periodo_ini     DATE    NOT NULL,
    periodo_fim     DATE    NOT NULL,
    gozo_ini        DATE,
    gozo_fim        DATE,
    dias_direito    INT     NOT NULL DEFAULT 30,
    dias_gozados    INT     NOT NULL DEFAULT 0,
    dias_abono      INT     NOT NULL DEFAULT 0,
    status          TEXT    NOT NULL DEFAULT 'pendente'
                            CHECK (status IN ('pendente','aprovado','em_gozo','concluido','cancelado')),
    observacoes     TEXT    NOT NULL DEFAULT '',
    aprovado_por    UUID    REFERENCES users(id) ON DELETE SET NULL,
    aprovado_em     TIMESTAMPTZ,
    criado_em       TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em   TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_ferias_tenant_func
    ON ferias (tenant_id, funcionario_id);

-- ─────────────────────────────────────────────────────────────────────────────
-- Afastamentos
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS afastamentos (
    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 (
                                'atestado_medico','licenca_maternidade','licenca_paternidade',
                                'acidente_trabalho','doenca_profissional','outros'
                            )),
    data_ini        DATE    NOT NULL,
    data_fim        DATE,
    dias            INT,
    cid             TEXT    NOT NULL DEFAULT '',
    descricao       TEXT    NOT NULL DEFAULT '',
    documento_url   TEXT    NOT NULL DEFAULT '',
    status          TEXT    NOT NULL DEFAULT 'ativo'
                            CHECK (status IN ('ativo','encerrado','cancelado')),
    criado_em       TIMESTAMPTZ NOT NULL DEFAULT now(),
    atualizado_em   TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_afastamentos_tenant_func
    ON afastamentos (tenant_id, funcionario_id);

CREATE INDEX IF NOT EXISTS idx_afastamentos_datas
    ON afastamentos (tenant_id, data_ini);

-- ─────────────────────────────────────────────────────────────────────────────
-- Rescisões
-- ─────────────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS rescisoes (
    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 (
                                  'sem_justa_causa','com_justa_causa','pedido_demissao',
                                  'acordo_mutuo','aposentadoria','falecimento','outros'
                              )),
    data_desligamento DATE    NOT NULL,
    aviso_previo      TEXT    NOT NULL DEFAULT 'trabalhado'
                              CHECK (aviso_previo IN ('trabalhado','indenizado','dispensado','nao_aplicavel')),
    saldo_ferias_dias INT     NOT NULL DEFAULT 0,
    banco_horas_min   INT     NOT NULL DEFAULT 0,
    observacoes       TEXT    NOT NULL DEFAULT '',
    criado_em         TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_rescisoes_tenant_func
    ON rescisoes (tenant_id, funcionario_id);

-- +goose StatementEnd

-- +goose StatementBegin
-- ─────────────────────────────────────────────────────────────────────────────
-- View: saldo banco de horas
-- ─────────────────────────────────────────────────────────────────────────────
CREATE OR REPLACE VIEW v_saldo_banco_horas AS
SELECT
    tenant_id,
    funcionario_id,
    SUM(minutos) AS saldo_minutos
FROM banco_horas
GROUP BY tenant_id, funcionario_id;
-- +goose StatementEnd

-- +goose StatementBegin
-- ─────────────────────────────────────────────────────────────────────────────
-- Permissões ponto — sistema usa users.permissoes TEXT[]
-- ─────────────────────────────────────────────────────────────────────────────

-- owner e admin: acesso total
UPDATE users
SET permissoes = array_cat(
    permissoes,
    ARRAY['ponto:read','ponto:write','ponto:relatorio']
)
WHERE role IN ('owner','admin')
  AND NOT ('*:*' = ANY(permissoes))
  AND NOT ('ponto:read' = ANY(permissoes));

-- manager: leitura + escrita + relatório
UPDATE users
SET permissoes = array_cat(
    permissoes,
    ARRAY['ponto:read','ponto:write','ponto:relatorio']
)
WHERE role = 'manager'
  AND NOT ('ponto:read' = ANY(permissoes))
  AND NOT ('*:*' = ANY(permissoes));

-- operador: leitura + escrita (bater ponto)
UPDATE users
SET permissoes = array_cat(
    permissoes,
    ARRAY['ponto:read','ponto:write']
)
WHERE role = 'operador'
  AND NOT ('ponto:read' = ANY(permissoes))
  AND NOT ('*:*' = ANY(permissoes));

-- vendedor: apenas leitura
UPDATE users
SET permissoes = array_append(permissoes, 'ponto:read')
WHERE role = 'vendedor'
  AND NOT ('ponto:read' = ANY(permissoes))
  AND NOT ('*:*' = ANY(permissoes));

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DROP VIEW  IF EXISTS v_saldo_banco_horas;
DROP TABLE IF EXISTS rescisoes;
DROP TABLE IF EXISTS afastamentos;
DROP TABLE IF EXISTS ferias;
DROP TABLE IF EXISTS banco_horas;
DROP TABLE IF EXISTS funcionario_jornadas;
DROP TABLE IF EXISTS jornadas;
DROP TABLE IF EXISTS registros_ponto;
-- +goose StatementEnd
