<?php

namespace App\Controllers;

use App\Traits\ResponseTrait;
use CodeIgniter\Controller;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
use CodeIgniter\Cookie\Cookie;

/**
 * AuthV2 Controller
 * 
 * Handles authentication for V2 UI
 * Separate from the main Auth controller to avoid conflicts
 */
class AuthV2Controller extends Controller
{
    use ResponseTrait;

    protected $db;

    public function __construct()
    {
        $this->db = \Config\Database::connect();
    }

    /**
     * Check authentication status
     * GET /v2/auth/check
     */
    public function checkAuth()
    {
        $token = $this->request->getCookie('token');
        $key = getenv('JWT_SECRET');

        if (!$token) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'No token found'
            ], 401);
        }

        try {
            $decodedPayload = JWT::decode($token, new Key($key, 'HS256'));

            return $this->respond([
                'status'  => 'success',
                'message' => 'Authenticated',
                'data'    => $decodedPayload
            ], 200);

        } catch (ExpiredException $e) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Token expired'
            ], 401);

        } catch (SignatureInvalidException $e) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Invalid token signature'
            ], 401);

        } catch (BeforeValidException $e) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Token not valid yet'
            ], 401);

        } catch (\Exception $e) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Invalid token: ' . $e->getMessage()
            ], 401);
        }
    }

    /**
     * Login user
     * POST /v2/auth/login
     */
    public function login()
    {
        $username = $this->request->getVar('username');
        $password = $this->request->getVar('password');
        $key = getenv('JWT_SECRET');

        // Validate username
        if (!$username) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Username is required'
            ], 400);
        }

        // Find user
        $sql = "SELECT * FROM users WHERE username = " . $this->db->escape($username);
        $query = $this->db->query($sql);
        $row = $query->getResultArray();

        if (!$row) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'User not found'
            ], 401);
        }

        $row = $row[0];

        // Verify password
        if (!password_verify($password, $row['password'])) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Invalid password'
            ], 401);
        }

        // Create JWT payload
        $exp = time() + 864000; // 10 days
        $payload = [
            'userid'   => $row['id'],
            'roleid'   => $row['role_id'],
            'username' => $row['username'],
            'exp'      => $exp
        ];

        try {
            $jwt = JWT::encode($payload, $key, 'HS256');
        } catch (\Exception $e) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Error generating JWT: ' . $e->getMessage()
            ], 500);
        }

        // Detect if HTTPS is being used
        $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';

        // Set HTTP-only cookie
        $this->response->setCookie([
            'name'     => 'token',
            'value'    => $jwt,
            'expire'   => 864000,
            'path'     => '/',
            'secure'   => $isSecure,  // false for localhost HTTP
            'httponly' => true,
            'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
        ]);

        return $this->respond([
            'status'  => 'success',
            'message' => 'Login successful',
            'data'    => [
                'username' => $row['username'],
                'role_id'  => $row['role_id']
            ]
        ], 200);
    }

    /**
     * Logout user
     * POST /v2/auth/logout
     */
    public function logout()
    {
        // Detect if HTTPS is being used
        $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';

        // Clear the token cookie
        return $this->response->setCookie([
            'name'     => 'token',
            'value'    => '',
            'expire'   => time() - 3600,
            'path'     => '/',
            'secure'   => $isSecure,
            'httponly' => true,
            'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
        ])->setJSON([
            'status'  => 'success',
            'message' => 'Logout successful'
        ]);
    }

    /**
     * Register new user
     * POST /v2/auth/register
     */
    public function register()
    {
        $username = strtolower($this->request->getJsonVar('username'));
        $password = $this->request->getJsonVar('password');

        // Validate input
        if (empty($username) || empty($password)) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Username and password are required'
            ], 400);
        }

        // Check for existing username
        $exists = $this->db->query("SELECT id FROM users WHERE username = ?", [$username])->getRow();
        if ($exists) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Username already exists'
            ], 409);
        }

        // Hash password
        $hashedPassword = password_hash($password, PASSWORD_DEFAULT);

        // Insert user
        $this->db->transStart();
        $this->db->query(
            "INSERT INTO users(username, password, role_id) VALUES(?, ?, ?)",
            [$username, $hashedPassword, 1]
        );
        $this->db->transComplete();

        if ($this->db->transStatus() === false) {
            return $this->respond([
                'status'  => 'failed',
                'message' => 'Failed to create user'
            ], 500);
        }

        return $this->respond([
            'status'  => 'success',
            'message' => 'User ' . $username . ' successfully created'
        ], 201);
    }
}
