<?php

namespace App\Controllers;

use App\Core\Auth;
use App\Core\AuditLog;
use App\Core\Database;
use App\Core\Permission;
use App\Core\Router;
use App\Core\Totp;

class ProfileController
{
    private function table(string $type): string
    {
        return $type === 'superadmin' ? 'superadmins' : ($type === 'manager' ? 'managers' : 'employees');
    }

    public function show(): void
    {
        $user = Permission::requireLogin();
        $flash = $_SESSION['flash'] ?? null;
        unset($_SESSION['flash']);

        $pendingSecret = $_SESSION['pending_2fa_setup_secret'] ?? null;
        $qrUrl = $pendingSecret ? Totp::qrCodeUrl($pendingSecret, $user['username'] ?? $user['name']) : null;

        require __DIR__ . '/../Views/profile/show.php';
    }

    public function beginTwoFactorSetup(): void
    {
        $user = Permission::requireLogin();
        $_SESSION['pending_2fa_setup_secret'] = \App\Core\Totp::generateSecret();
        Router::redirect('/profile');
    }

    public function confirmTwoFactorSetup(): void
    {
        $user = Permission::requireLogin();
        $secret = $_SESSION['pending_2fa_setup_secret'] ?? null;
        $code = trim($_POST['code'] ?? '');

        if (!$secret || !Totp::verify($secret, $code)) {
            $_SESSION['flash'] = ['type' => 'error', 'msg' => 'Incorrect code. Please scan the QR code again and try the current 6-digit code.'];
            Router::redirect('/profile');
        }

        $db = Database::connection();
        $table = $this->table($user['user_type']);
        $db->prepare("UPDATE `{$table}` SET two_factor_enabled = 1, two_factor_secret = :s WHERE id = :id")
           ->execute(['s' => $secret, 'id' => $user['user_id']]);

        unset($_SESSION['pending_2fa_setup_secret']);

        AuditLog::record($user['user_type'], $user['user_id'], $user['name'], 'user', (string)$user['user_id'], 'update', null, ['two_factor' => 'enabled']);

        $_SESSION['flash'] = ['type' => 'success', 'msg' => 'Two-factor authentication is now enabled on your account.'];
        Router::redirect('/profile');
    }

    public function disableTwoFactor(): void
    {
        $user = Permission::requireLogin();
        $password = $_POST['password'] ?? '';

        $db = Database::connection();
        $table = $this->table($user['user_type']);
        $stmt = $db->prepare("SELECT password_hash FROM `{$table}` WHERE id = :id");
        $stmt->execute(['id' => $user['user_id']]);
        $row = $stmt->fetch();

        if (!$row || !password_verify($password, $row['password_hash'])) {
            $_SESSION['flash'] = ['type' => 'error', 'msg' => 'Incorrect password. Two-factor authentication was not disabled.'];
            Router::redirect('/profile');
        }

        $db->prepare("UPDATE `{$table}` SET two_factor_enabled = 0, two_factor_secret = NULL WHERE id = :id")
           ->execute(['id' => $user['user_id']]);

        AuditLog::record($user['user_type'], $user['user_id'], $user['name'], 'user', (string)$user['user_id'], 'update', null, ['two_factor' => 'disabled']);

        $_SESSION['flash'] = ['type' => 'success', 'msg' => 'Two-factor authentication has been disabled.'];
        Router::redirect('/profile');
    }

    public function changePassword(): void
    {
        $user = Permission::requireLogin();
        $current = $_POST['current_password'] ?? '';
        $new = $_POST['new_password'] ?? '';

        $db = Database::connection();
        $table = $this->table($user['user_type']);
        $stmt = $db->prepare("SELECT password_hash FROM `{$table}` WHERE id = :id");
        $stmt->execute(['id' => $user['user_id']]);
        $row = $stmt->fetch();

        if (!$row || !password_verify($current, $row['password_hash'])) {
            $_SESSION['flash'] = ['type' => 'error', 'msg' => 'Current password is incorrect.'];
            Router::redirect('/profile');
        }

        if (strlen($new) < 8) {
            $_SESSION['flash'] = ['type' => 'error', 'msg' => 'New password must be at least 8 characters.'];
            Router::redirect('/profile');
        }

        $db->prepare("UPDATE `{$table}` SET password_hash = :p WHERE id = :id")
           ->execute(['p' => password_hash($new, PASSWORD_DEFAULT), 'id' => $user['user_id']]);

        AuditLog::record($user['user_type'], $user['user_id'], $user['name'], 'user', (string)$user['user_id'], 'update', null, ['password' => 'changed']);

        $_SESSION['flash'] = ['type' => 'success', 'msg' => 'Password updated successfully.'];
        Router::redirect('/profile');
    }

    /** Forced first-login password change (no "current password" needed - the temp one just worked). */
    public function showForceChangePassword(): void
    {
        if (empty($_SESSION['must_change_password'])) {
            Router::redirect('/login');
        }
        $error = $_SESSION['force_change_error'] ?? null;
        unset($_SESSION['force_change_error']);
        require __DIR__ . '/../Views/auth/force_change_password.php';
    }

    public function submitForceChangePassword(): void
    {
        if (empty($_SESSION['must_change_password']) || !Auth::check()) {
            Router::redirect('/login');
        }

        $user = Auth::currentUser();
        $new = $_POST['password'] ?? '';
        $confirm = $_POST['password_confirm'] ?? '';

        if (strlen($new) < 8) {
            $_SESSION['force_change_error'] = 'Password must be at least 8 characters.';
            Router::redirect('/change-password');
        }
        if ($new !== $confirm) {
            $_SESSION['force_change_error'] = 'Passwords do not match.';
            Router::redirect('/change-password');
        }

        $table = $this->table($user['user_type']);
        $db = Database::connection();
        $db->prepare("UPDATE `{$table}` SET password_hash = :p, force_password_change = 0 WHERE id = :id")
           ->execute(['p' => password_hash($new, PASSWORD_DEFAULT), 'id' => $user['user_id']]);

        unset($_SESSION['must_change_password']);
        AuditLog::record($user['user_type'], $user['user_id'], $user['name'], 'user', (string)$user['user_id'], 'update', null, ['password' => 'changed_forced']);

        if ($user['is_super_admin']) {
            Router::redirect('/admin/users');
        }
        Router::redirect('/workspace');
    }
}
