<?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;

class AuthController extends Controller
{
    use ResponseTrait;

    protected $db;

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

    // ok
    public function checkAuth()
    {
        $token = $this->request->getCookie('token');
        $key = getenv('JWT_SECRET');

        // Jika token FE tidak ada langsung kabarkan failed
        if (!$token) {
            return $this->respond([
                'status' => 'failed',
                'message' => 'No token found'
            ], 401);
        }

        try {
            // Decode Token dengan Key yg ada di .env
            $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',
                'data' => []
            ], 401);

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

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

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

    // ok
    // public function login() {

    //     // Ambil dari JSON Form dan Key .env
    //     $username = $this->request->getVar('username');
    //     $password = $this->request->getVar('password');
    //     $key = getenv('JWT_SECRET');

    //     if (!$username) {
    //         return $this->fail('Username required.', 400);
    //     }

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

    //     if (!$row) { return $this->fail('User not found.', 401); }
    //     $row = $row[0];
    //     if (!password_verify($password, $row['password'])) {
    //         return $this->fail('Invalid password.', 401);
    //     }

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

    //     try {
    //         // Melakukan Hash terhadap Payload dengan Kunci .env menggunakan Algortima HMAC + SHA-256
    //         $jwt = JWT::encode($payload, $key, 'HS256');
    //     } catch (Exception $e) {
    //         return $this->fail('Error generating JWT: ' . $e->getMessage(), 500);
    //     }

    //     // Kirim Respon ke HttpOnly yg akan disimpan di browser dan tidak akan dapat diakses oleh siapapun
    //     // $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
    //     $this->response->setCookie([
    //         // 'name'     => 'token',              // nama token
    //         // 'value'    => $jwt,                 // value dari jwt yg sudah di hash
    //         // 'expire'   => 864000,               // 10 hari
    //         // 'path'     => '/',                  // valid untuk semua path
    //         // 'secure'   => $isSecure,            // true for HTTPS, false for HTTP (localhost)
    //         // 'httponly' => true,                 // dipakai agar cookie berikut tidak dapat diakses oleh javascript
    //         // 'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX 
    //     ]);


    //     // Response tanpa token di body
    //     return $this->respond([
    //         'status'  => 'success',
    //         'code' => 200,
    //         'message' => 'Login successful'
    //     ], 200);
    // }
    public function login()
    {

        // Ambil dari JSON Form dan Key .env
        $username = $this->request->getVar('username');
        $password = $this->request->getVar('password');
        $key = getenv('JWT_SECRET');

        if (!$username) {
            return $this->fail('Username required.', 400);
        }

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

        if (!$row) {
            return $this->fail('User not found.', 401);
        }
        $row = $row[0];
        if (!password_verify($password, $row['password'])) {
            return $this->fail('Invalid password.', 401);
        }

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

        try {
            // Melakukan Hash terhadap Payload dengan Kunci .env menggunakan Algortima HMAC + SHA-256
            $jwt = JWT::encode($payload, $key, 'HS256');
        } catch (\Exception $e) {
            return $this->fail('Error generating JWT: ' . $e->getMessage(), 500);
        }

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

        // Kirim Respon ke HttpOnly yg akan disimpan di browser dan tidak akan dapat diakses oleh siapapun
        $this->response->setCookie([
            'name' => 'token',              // nama token
            'value' => $jwt,                 // value dari jwt yg sudah di hash
            'expire' => 864000,               // 10 hari
            'path' => '/',                  // valid untuk semua path
            'secure' => $isSecure,
            'httponly' => true,                 // dipakai agar cookie berikut tidak dapat diakses oleh javascript
            'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
        ]);

        // Response tanpa token di body
        return $this->respond([
            'status' => 'success',
            'code' => 200,
            'message' => 'Login successful'
        ], 200);
    }

    // ok
    // public function logout() {
    //     // Definisikan ini pada cookies browser, harus sama dengan cookies login
    //     // $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
    //     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',
    //         'code' => 200, 
    //         'message'   => 'Logout successful'
    //     ], 200);
    // }
    public function logout()
    {
        // Detect if HTTPS is being used
        $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
        
        // Definisikan ini pada cookies browser, harus sama dengan cookies login
        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',
                    'code' => 200,
                    'message' => 'Logout successful'
                ], 200);
    }

    // ok
    public function register()
    {

        $username = strtolower($this->request->getJsonVar('username'));
        $password = $this->request->getJsonVar('password');

        // Validasi Awal Dari BE
        if (empty($username) || empty($password)) {
            return $this->respond([
                'status' => 'failed',
                'code' => 400,
                'message' => 'Username and password are required'
            ], 400); // Gunakan 400 Bad Request
        }

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

        $hashedPassword = password_hash($password, PASSWORD_DEFAULT);

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

        // Cek status transaksi
        if ($this->db->transStatus() === false) {
            return $this->respond([
                'status' => 'error',
                'code' => 500,
                'message' => 'Failed to create user. Please try again later.'
            ], 500);
        }

        // Respon sukses jika kueri berhasil
        return $this->respond([
            'status' => 'success',
            'code' => 201,
            'message' => 'User ' . $username . ' successfully created.'
        ], 201);

    }

    // public function change_pass() {
    //     $db = \Config\Database::connect();
    //     $username = $this->request->getJsonVar('username');
    //     $password = $this->request->getJsonVar('password');
    //     $password = password_hash($password, PASSWORD_DEFAULT);

    //     $master = $this->request->getJsonVar('master');
    //     $masterkey = getenv('masterkey');

    //     if($master != $masterkey) {
    //         return $this->fail('Invalid master key.', 401);
    //     }

    //     $sql = "update users set password='$password' where username='$username'";
    //     $query = $db->query($sql);
    //     $response = [
    //         'message' => "Password Changed for $username"
    //     ];
    //     return $this->respond($response);
    // }

    public function coba()
    {

        $token = $this->request->getCookie('token');
        $key = getenv('JWT_SECRET');

        // Decode Token dengan Key yg ada di .env
        $decodedPayload = JWT::decode($token, new Key($key, 'HS256'));

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

}
