<?php
declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class TaskSr44606 extends AbstractMigration
{
    public function up(): void
    {
        $this->execute(<<<SQL
            CREATE TABLE sistema.usuario_historico_senha (
                id SERIAL,
                id_usuario INTEGER NOT NULL,
                ds_senha VARCHAR (255) NOT NULL,
                CONSTRAINT pk_usuario_historico_senha PRIMARY KEY (id),
                CONSTRAINT fk_id_usuario FOREIGN KEY (id_usuario) REFERENCES sistema.usuarios(id)
            ) INHERITS (public.campos_default);

            ALTER TABLE sistema.usuarios ADD COLUMN dt_expiracao_senha TIMESTAMP;
            ALTER TABLE sistema.usuarios ADD COLUMN fl_notificado_expiracao_senha BOOLEAN DEFAULT FALSE;
            ALTER TABLE sistema.usuarios ADD COLUMN fl_notificado_bloqueio_inatividade BOOLEAN DEFAULT FALSE;
            ALTER TABLE sistema.usuarios ADD COLUMN fl_bloqueio_inatividade BOOLEAN DEFAULT FALSE;

            UPDATE sistema.usuarios SET dt_expiracao_senha = '2999-12-31 00:00:00'
                WHERE id = 2068 OR ds_nome_usuario ilike 'vistoriador%';
SQL
);

        $usuarios = $this->fetchAll(<<<SQL
            SELECT
                id,
                u.dt_criacao AS data_controle,
                CASE WHEN log_acesso.id_usuario IS NULL THEN 6
                    ELSE EXTRACT(year FROM age(NOW(), log_acesso.data_acesso))*12 + EXTRACT(month FROM age(NOW(), log_acesso.data_acesso)) 
                END AS meses_inativo
            FROM 
                sistema.usuarios u
            LEFT JOIN (
                SELECT
                    id_usuario,
                    max(data_acesso) as data_acesso
                FROM
                    log.log_acesso
                WHERE 
                    fl_ativo IS TRUE
                GROUP BY
                    id_usuario
            ) log_acesso ON log_acesso.id_usuario = u.id
            WHERE 
                u.fl_ativo IS TRUE
                AND u.id <> 2068
SQL
);

        foreach ($usuarios as $usuario) {
            // Bloqueia usuário
            if ($usuario['meses_inativo'] >= 6) {
                $this->execute(<<<SQL
                    UPDATE sistema.usuarios SET fl_bloqueio_inatividade = TRUE WHERE id = {$usuario['id']}
SQL
                );
                continue;
            }

            $dataAtual = new DateTime('now');
            $dataControle = new DateTime($usuario['data_controle']);
            $mesesASomar = $diferencaMeses = abs((int)$dataAtual->format('n') - (int)$dataControle->format('n'));

            if ($diferencaMeses > 4) {
                $mesesASomar = $diferencaMeses % 4;
            }

            $mesesASomar = $mesesASomar == 0 ? 4 : $mesesASomar;

            $dataAtual->add(DateInterval::createFromDateString("{$mesesASomar} month"));
            $dataExpiracaoSenha = $dataAtual->format('Y-m-d H:i:s');

            $this->execute(<<<SQL
                UPDATE sistema.usuarios SET dt_expiracao_senha = '{$dataExpiracaoSenha}' WHERE id = {$usuario['id']}
SQL
);
        }
    }

    public function down(): void
    {
        $this->execute(<<<SQL
            ALTER TABLE sistema.usuarios DROP COLUMN dt_expiracao_senha;
            ALTER TABLE sistema.usuarios DROP COLUMN fl_notificado_expiracao_senha;
            ALTER TABLE sistema.usuarios DROP COLUMN fl_notificado_bloqueio_inatividade;
            ALTER TABLE sistema.usuarios DROP COLUMN fl_bloqueio_inatividade;
            DROP TABLE sistema.usuario_historico_senha;
SQL
);
    }
}
