<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\DB;

class AdminController extends Controller
{
    public function dashboard(): void
    {
        $totalEmpresas = (int)(DB::pdo()->query("SELECT COUNT(*) AS c FROM tenants")->fetch()['c'] ?? 0);
        $empAtivas = (int)(DB::pdo()->query("SELECT COUNT(*) AS c FROM tenants WHERE status = 'ativo'")->fetch()['c'] ?? 0);
        $empBloqueadas = (int)(DB::pdo()->query("SELECT COUNT(*) AS c FROM tenants WHERE status IN ('bloqueado','inativo')")->fetch()['c'] ?? 0);
        $mes = $_GET['mes'] ?? date('Y-m');
        $inicio = $mes . '-01 00:00:00';
        $fim = date('Y-m-t 23:59:59', strtotime($inicio));
        $fatMensal = DB::pdo()->prepare("SELECT COALESCE(SUM(amount),0) AS total FROM payments WHERE status = 'approved' AND created_at BETWEEN ? AND ?");
        $fatMensal->execute([$inicio, $fim]);
        $faturamentoMensal = (float)($fatMensal->fetch()['total'] ?? 0);
        $mrrStmt = DB::pdo()->query("SELECT COALESCE(SUM(p.price),0) AS mrr FROM tenants t LEFT JOIN plans p ON p.id = t.plan_id WHERE t.status = 'ativo'");
        $mrr = (float)($mrrStmt->fetch()['mrr'] ?? 0);
        $notasMesStmt = DB::pdo()->prepare("SELECT COUNT(*) AS c FROM invoices WHERE data_emissao BETWEEN ? AND ?");
        $notasMesStmt->execute([$inicio, $fim]);
        $notasMes = (int)($notasMesStmt->fetch()['c'] ?? 0);
        $serieFat = [];
        $serieNotas = [];
        for ($i = 5; $i >= 0; $i--) {
            $m = date('Y-m', strtotime("-$i month"));
            $ini = $m . '-01 00:00:00';
            $end = date('Y-m-t 23:59:59', strtotime($ini));
            $s1 = DB::pdo()->prepare("SELECT COALESCE(SUM(amount),0) AS total FROM payments WHERE status = 'approved' AND created_at BETWEEN ? AND ?");
            $s1->execute([$ini, $end]);
            $serieFat[] = ['mes' => $m, 'valor' => (float)($s1->fetch()['total'] ?? 0)];
            $s2 = DB::pdo()->prepare("SELECT COUNT(*) AS c FROM invoices WHERE data_emissao BETWEEN ? AND ?");
            $s2->execute([$ini, $end]);
            $serieNotas[] = ['mes' => $m, 'qtde' => (int)($s2->fetch()['c'] ?? 0)];
        }
        $this->view('admin/dashboard', [
            'mes' => $mes,
            'totalEmpresas' => $totalEmpresas,
            'empAtivas' => $empAtivas,
            'empBloqueadas' => $empBloqueadas,
            'faturamentoMensal' => $faturamentoMensal,
            'mrr' => $mrr,
            'notasMes' => $notasMes,
            'serieFat' => $serieFat,
            'serieNotas' => $serieNotas,
        ]);
    }
    public function empresas(): void
    {
        $rows = DB::pdo()->query("SELECT t.id, t.name, t.razao_social, t.cnpj, t.status, t.uf, t.ambiente, p.name AS plano, p.limit_notas, p.price FROM tenants t LEFT JOIN plans p ON p.id = t.plan_id ORDER BY t.created_at DESC")->fetchAll();
        $this->view('admin/empresas', ['empresas' => $rows]);
    }

    public function pagamentos(): void
    {
        $rows = DB::pdo()->query("SELECT pay.id, pay.status, pay.amount, pay.created_at, t.name AS empresa, t.cnpj, p.name AS plano FROM payments pay LEFT JOIN tenants t ON t.id = pay.tenant_id LEFT JOIN plans p ON p.id = pay.plan_id ORDER BY pay.created_at DESC")->fetchAll();
        $this->view('admin/pagamentos', ['pagamentos' => $rows]);
    }

    public function plans(): void
    {
        $rows = DB::pdo()->query("SELECT * FROM plans ORDER BY id ASC")->fetchAll();
        $this->view('admin/plans', ['plans' => $rows]);
    }

    public function planForm(): void
    {
        $id = (int)($_GET['id'] ?? 0);
        $plan = null;
        if ($id) {
            $stmt = DB::pdo()->prepare("SELECT * FROM plans WHERE id = ?");
            $stmt->execute([$id]);
            $plan = $stmt->fetch();
        }
        $this->view('admin/plan_form', ['plan' => $plan]);
    }

    public function planSave(): void
    {
        $id = (int)($_POST['id'] ?? 0);
        $name = trim($_POST['name'] ?? '');
        $limit = (int)($_POST['limit_notas'] ?? 0);
        $price = (float)($_POST['price'] ?? 0);
        $features = trim($_POST['features'] ?? '');
        $now = date('Y-m-d H:i:s');
        if ($id) {
            $stmt = DB::pdo()->prepare("UPDATE plans SET name = ?, limit_notas = ?, price = ?, features = ?, updated_at = ? WHERE id = ?");
            $stmt->execute([$name, $limit, $price, $features, $now, $id]);
        } else {
            $stmt = DB::pdo()->prepare("INSERT INTO plans (name, limit_notas, price, features, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)");
            $stmt->execute([$name, $limit, $price, $features, $now, $now]);
        }
        header('Location: /admin/plans');
    }

    public function planDelete(): void
    {
        $id = (int)($_POST['id'] ?? 0);
        if ($id) {
            $stmt = DB::pdo()->prepare("DELETE FROM plans WHERE id = ?");
            $stmt->execute([$id]);
        }
        header('Location: /admin/plans');
    }

    public function assinaturas(): void
    {
        $rows = DB::pdo()->query("SELECT a.id, a.status, a.data_inicio, a.data_fim, t.name AS empresa, p.name AS plano FROM assinaturas a LEFT JOIN tenants t ON t.id = a.empresa_id LEFT JOIN plans p ON p.id = a.plano_id ORDER BY a.data_inicio DESC")->fetchAll();
        $this->view('admin/assinaturas', ['assinaturas' => $rows]);
    }

    public function assinaturaRenovar(): void
    {
        $id = (int)($_POST['id'] ?? 0);
        if ($id) {
            $stmt = DB::pdo()->prepare("UPDATE assinaturas SET status = 'ativa', data_fim = DATE_ADD(data_fim, INTERVAL 1 MONTH), updated_at = ? WHERE id = ?");
            $stmt->execute([date('Y-m-d H:i:s'), $id]);
        }
        header('Location: /admin/assinaturas');
    }

    public function assinaturaCancelar(): void
    {
        $id = (int)($_POST['id'] ?? 0);
        if ($id) {
            $stmt = DB::pdo()->prepare("UPDATE assinaturas SET status = 'cancelada', updated_at = ? WHERE id = ?");
            $stmt->execute([date('Y-m-d H:i:s'), $id]);
        }
        header('Location: /admin/assinaturas');
    }

    public function webhooks(): void
    {
        $rows = DB::pdo()->query("SELECT * FROM webhook_logs ORDER BY id DESC LIMIT 200")->fetchAll();
        $this->view('admin/webhooks', ['webhooks' => $rows]);
    }

    public function logsSefaz(): void
    {
        $rows = DB::pdo()->query("SELECT * FROM sefaz_logs ORDER BY id DESC LIMIT 200")->fetchAll();
        $this->view('admin/logs_sefaz', ['logs' => $rows]);
    }

    public function logsErro(): void
    {
        $rows = DB::pdo()->query("SELECT * FROM sefaz_failed ORDER BY id DESC LIMIT 200")->fetchAll();
        $this->view('admin/logs_erro', ['logs' => $rows]);
    }

    public function logsLogin(): void
    {
        $rows = DB::pdo()->query("SELECT * FROM login_logs ORDER BY id DESC LIMIT 200")->fetchAll();
        $this->view('admin/logs_login', ['logs' => $rows]);
    }

    public function logsAdmin(): void
    {
        $rows = DB::pdo()->query("SELECT * FROM admin_logs ORDER BY id DESC LIMIT 200")->fetchAll();
        $this->view('admin/logs_admin', ['logs' => $rows]);
    }
    
    public function usuarios(): void
    {
        $rows = DB::pdo()->query("SELECT u.id, u.name, u.email, u.role, u.tenant_id, t.name AS empresa FROM users u LEFT JOIN tenants t ON t.id = u.tenant_id ORDER BY u.created_at DESC")->fetchAll();
        $this->view('admin/usuarios', ['usuarios' => $rows]);
    }
    
    public function empresaUsuarios(): void
    {
        $tenantId = (int)($_GET['id'] ?? 0);
        $tenant = null;
        if ($tenantId) {
            $t = DB::pdo()->prepare("SELECT id, name, cnpj FROM tenants WHERE id = ?");
            $t->execute([$tenantId]);
            $tenant = $t->fetch();
        }
        $rows = [];
        if ($tenant) {
            $u = DB::pdo()->prepare("SELECT id, name, email, role FROM users WHERE tenant_id = ? ORDER BY created_at DESC");
            $u->execute([$tenantId]);
            $rows = $u->fetchAll();
        }
        $this->view('admin/empresa_usuarios', ['tenant' => $tenant, 'usuarios' => $rows]);
    }
    
    public function empresaUsuarioSalvar(): void
    {
        $tenantId = (int)($_POST['tenant_id'] ?? 0);
        $name = trim($_POST['name'] ?? '');
        $email = trim($_POST['email'] ?? '');
        $password = $_POST['password'] ?? '';
        $role = $_POST['role'] ?? 'empresa';
        if ($tenantId && $name !== '' && $email !== '' && $password !== '' && in_array($role, ['admin','empresa'], true)) {
            $exists = DB::pdo()->prepare("SELECT id FROM users WHERE email = ?");
            $exists->execute([$email]);
            if (!$exists->fetch()) {
                $hash = password_hash($password, PASSWORD_DEFAULT);
                $stmt = DB::pdo()->prepare("INSERT INTO users (tenant_id, name, email, password, role, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)");
                $stmt->execute([$tenantId, $name, $email, $hash, $role, date('Y-m-d H:i:s'), date('Y-m-d H:i:s')]);
                try {
                    $log = DB::pdo()->prepare("INSERT INTO admin_logs (admin_user_id, action, target_tenant_id, details, created_at) VALUES (?, ?, ?, ?, ?)");
                    $log->execute([$_SESSION['user_id'] ?? null, 'criar_usuario_empresa', $tenantId, $email, date('Y-m-d H:i:s')]);
                } catch (\Throwable $e) {
                }
            }
        }
        header('Location: /admin/empresa/usuarios?id=' . $tenantId);
    }
    
    public function empresaUsuarioSenha(): void
    {
        $tenantId = (int)($_POST['tenant_id'] ?? 0);
        $userId = (int)($_POST['user_id'] ?? 0);
        $senha = $_POST['senha'] ?? '';
        if ($tenantId && $userId && $senha !== '') {
            $hash = password_hash($senha, PASSWORD_DEFAULT);
            $stmt = DB::pdo()->prepare("UPDATE users SET password = ?, updated_at = ? WHERE id = ? AND tenant_id = ?");
            $stmt->execute([$hash, date('Y-m-d H:i:s'), $userId, $tenantId]);
            try {
                $log = DB::pdo()->prepare("INSERT INTO admin_logs (admin_user_id, action, target_user_id, details, created_at) VALUES (?, ?, ?, ?, ?)");
                $log->execute([$_SESSION['user_id'] ?? null, 'trocar_senha_usuario', $userId, 'empresa', date('Y-m-d H:i:s')]);
            } catch (\Throwable $e) {
            }
        }
        header('Location: /admin/empresa/usuarios?id=' . $tenantId);
    }
    
    public function usuarioRoleSalvar(): void
    {
        $userId = (int)($_POST['user_id'] ?? 0);
        $role = $_POST['role'] ?? '';
        if ($userId && in_array($role, ['admin','empresa'], true)) {
            $stmt = DB::pdo()->prepare("UPDATE users SET role = ?, updated_at = ? WHERE id = ?");
            $stmt->execute([$role, date('Y-m-d H:i:s'), $userId]);
            try {
                $log = DB::pdo()->prepare("INSERT INTO admin_logs (admin_user_id, action, target_user_id, details, created_at) VALUES (?, ?, ?, ?, ?)");
                $log->execute([$_SESSION['user_id'] ?? null, 'trocar_role', $userId, $role, date('Y-m-d H:i:s')]);
            } catch (\Throwable $e) {
            }
        }
        header('Location: /admin/usuarios');
    }

    public function configuracoes(): void
    {
        $mpToken = DB::pdo()->query("SELECT svalue FROM settings WHERE skey = 'mercadopago.access_token'")->fetch()['svalue'] ?? '';
        $mpSecret = DB::pdo()->query("SELECT svalue FROM settings WHERE skey = 'mercadopago.webhook_secret'")->fetch()['svalue'] ?? '';
        $sefazAmb = DB::pdo()->query("SELECT svalue FROM settings WHERE skey = 'sefaz.ambiente'")->fetch()['svalue'] ?? '';
        $smtp = DB::pdo()->query("SELECT svalue FROM settings WHERE skey = 'smtp.server'")->fetch()['svalue'] ?? '';
        $apiToken = DB::pdo()->query("SELECT svalue FROM settings WHERE skey = 'api.token'")->fetch()['svalue'] ?? '';
        $this->view('admin/config', ['mpToken' => $mpToken, 'mpSecret' => $mpSecret, 'sefazAmb' => $sefazAmb, 'smtp' => $smtp, 'apiToken' => $apiToken]);
    }

    public function configuracoesSalvar(): void
    {
        $pairs = [
            'mercadopago.access_token' => $_POST['mercadopago_access_token'] ?? '',
            'mercadopago.webhook_secret' => $_POST['mercadopago_webhook_secret'] ?? '',
            'sefaz.ambiente' => $_POST['sefaz_ambiente'] ?? '',
            'smtp.server' => $_POST['smtp_server'] ?? '',
            'api.token' => $_POST['api_token'] ?? '',
        ];
        $now = date('Y-m-d H:i:s');
        foreach ($pairs as $k => $v) {
            $stmt = DB::pdo()->prepare("INSERT INTO settings (skey, svalue, updated_at) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE svalue = VALUES(svalue), updated_at = VALUES(updated_at)");
            $stmt->execute([$k, $v, $now]);
        }
        header('Location: /admin/config');
    }

    public function alterarStatus(): void
    {
        $tenantId = (int)($_POST['tenant_id'] ?? 0);
        $status = $_POST['status'] ?? '';
        if ($tenantId && in_array($status, ['ativo','inativo','bloqueado'], true)) {
            $stmt = DB::pdo()->prepare("UPDATE tenants SET status = ?, updated_at = ? WHERE id = ?");
            $stmt->execute([$status, date('Y-m-d H:i:s'), $tenantId]);
            try {
                $log = DB::pdo()->prepare("INSERT INTO admin_logs (admin_user_id, action, target_tenant_id, details, created_at) VALUES (?, ?, ?, ?, ?)");
                $log->execute([$_SESSION['user_id'] ?? null, 'alterar_status', $tenantId, $status, date('Y-m-d H:i:s')]);
            } catch (\Throwable $e) {
            }
        }
        header('Location: /admin/empresas');
    }

    public function trocarSenha(): void
    {
        $tenantId = (int)($_POST['tenant_id'] ?? 0);
        $senha = $_POST['senha'] ?? '';
        if ($tenantId && $senha !== '') {
            $hash = password_hash($senha, PASSWORD_DEFAULT);
            $stmt = DB::pdo()->prepare("UPDATE users SET password = ?, updated_at = ? WHERE tenant_id = ? AND role = 'admin'");
            $stmt->execute([$hash, date('Y-m-d H:i:s'), $tenantId]);
            try {
                $log = DB::pdo()->prepare("INSERT INTO admin_logs (admin_user_id, action, target_tenant_id, details, created_at) VALUES (?, ?, ?, ?, ?)");
                $log->execute([$_SESSION['user_id'] ?? null, 'trocar_senha', $tenantId, 'admin', date('Y-m-d H:i:s')]);
            } catch (\Throwable $e) {
            }
        }
        header('Location: /admin/empresas');
    }

    public function nova(): void
    {
        $plans = DB::pdo()->query("SELECT id, name FROM plans")->fetchAll();
        $this->view('admin/nova', ['plans' => $plans]);
    }

    public function salvar(): void
    {
        $name = trim($_POST['name'] ?? '');
        $razao = trim($_POST['razao_social'] ?? '');
        $cnpj = preg_replace('/\D+/', '', $_POST['cnpj'] ?? '');
        $uf = strtoupper($_POST['uf'] ?? '');
        $ambiente = $_POST['ambiente'] ?? 'homologacao';
        $planId = (int)($_POST['plan_id'] ?? 0);
        $email = trim($_POST['email'] ?? '');
        $senha = $_POST['senha'] ?? '';
        if ($name !== '' && $cnpj !== '' && $email !== '' && $senha !== '' && $planId > 0) {
            $now = date('Y-m-d H:i:s');
            $check = DB::pdo()->prepare("SELECT id FROM tenants WHERE cnpj = ?");
            $check->execute([$cnpj]);
            $row = $check->fetch();
            if ($row) {
                $tenantId = (int)$row['id'];
            } else {
                $insT = DB::pdo()->prepare("INSERT INTO tenants (name, razao_social, cnpj, uf, ambiente, plan_id, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, 'ativo', ?, ?)");
                $insT->execute([$name, $razao, $cnpj, $uf, $ambiente, $planId, $now, $now]);
                $tenantId = (int)DB::pdo()->lastInsertId();
            }
            $chkUser = DB::pdo()->prepare("SELECT id FROM users WHERE email = ?");
            $chkUser->execute([$email]);
            if (!$chkUser->fetch()) {
                $hash = password_hash($senha, PASSWORD_DEFAULT);
                $insU = DB::pdo()->prepare("INSERT INTO users (tenant_id, name, email, password, role, created_at, updated_at) VALUES (?, ?, ?, ?, 'admin', ?, ?)");
                $insU->execute([$tenantId, $name, $email, $hash, $now, $now]);
            }
            try {
                $log = DB::pdo()->prepare("INSERT INTO admin_logs (admin_user_id, action, target_tenant_id, details, created_at) VALUES (?, ?, ?, ?, ?)");
                $log->execute([$_SESSION['user_id'] ?? null, 'criar_empresa', $tenantId, $email, date('Y-m-d H:i:s')]);
            } catch (\Throwable $e) {
            }
        }
        header('Location: /admin/empresas');
    }
}
