<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Config\Database;
use App\Utils\JWT;
use App\Utils\Env;
use PDO;

class AuthController extends Controller {
    private $db;

    public function __construct() {
        $this->db = Database::getInstance()->getConnection();
    }

    public function register() {
        $input = $this->input();
        $this->validate($input, [
            'email' => 'required',
            'password' => 'required',
            'username' => 'required'
        ]);

        $linkSlug = $input['username']; // Use username as slug automatically

        // Check if email or username or slug exists
        $stmt = $this->db->prepare("SELECT id FROM users WHERE email = ? OR username = ? OR link_slug = ?");
        $stmt->execute([$input['email'], $input['username'], $linkSlug]);
        if ($stmt->fetch()) {
            $this->json(['error' => 'User already exists'], 409);
        }

        $passwordHash = password_hash($input['password'], PASSWORD_BCRYPT);
        
        $stmt = $this->db->prepare("INSERT INTO users (email, password_hash, username, display_name, link_slug, status) VALUES (?, ?, ?, ?, ?, 'online')");
        $stmt->execute([
            $input['email'], 
            $passwordHash, 
            $input['username'], 
            $input['username'], // Default display name
            $linkSlug
        ]);

        $userId = $this->db->lastInsertId();

        // Capture tracking info (wrapped in try-catch to prevent block if migration not run)
        try {
            $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
            $deviceInfo = isset($input['device_info']) ? json_encode($input['device_info']) : null;
            $stmt = $this->db->prepare("UPDATE users SET registration_ip = ?, last_ip = ?, device_info = ? WHERE id = ?");
            $stmt->execute([$ip, $ip, $deviceInfo, $userId]);
        } catch (\Exception $e) {
            error_log("[AuthController] Tracking failed during register: " . $e->getMessage());
        }
        $stmt = $this->db->prepare("SELECT * FROM users WHERE id = ?");
        $stmt->execute([$userId]);
        $newUser = $stmt->fetch();

        $isProfileComplete = $this->checkProfileComplete($newUser);
        $token = $this->generateToken($userId);

        $this->json(['token' => $token, 'user' => [
            'id' => $userId,
            'username' => $input['username'],
            'email' => $input['email'],
            'link_slug' => $linkSlug,
            'is_profile_complete' => $isProfileComplete
        ]], 201);
    }

    public function login() {
        $input = $this->input();
        
        $login = isset($input['login']) ? $input['login'] : (isset($input['email']) ? $input['email'] : null);
        
        if (!$login) {
             $this->json(['error' => 'Login (email or username) is required'], 422);
        }
        if (!isset($input['password'])) {
             $this->json(['error' => 'Password is required'], 422);
        }

        $stmt = $this->db->prepare("SELECT * FROM users WHERE email = ? OR username = ?");
        $stmt->execute([$login, $login]);
        $user = $stmt->fetch();

        if (!$user || !password_verify($input['password'], $user['password_hash'])) {
            $this->json(['error' => 'Invalid credentials'], 401);
        }

        if ($user['is_banned']) {
            $this->json(['error' => 'Account banned: ' . $user['ban_reason']], 403);
        }

        // Update status to online and capture tracking info
        try {
            $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
            $deviceInfo = isset($input['device_info']) ? json_encode($input['device_info']) : null;
            
            $update = $this->db->prepare("UPDATE users SET status = 'online', last_seen_at = NOW(), last_ip = ?, device_info = COALESCE(?, device_info) WHERE id = ?");
            $update->execute([$ip, $deviceInfo, $user['id']]);
        } catch (\Exception $e) {
            error_log("[AuthController] Tracking failed during login: " . $e->getMessage());
            // Fallback: update status at least if columns missing
            $this->db->prepare("UPDATE users SET status = 'online', last_seen_at = NOW() WHERE id = ?")->execute([$user['id']]);
        }

        $isProfileComplete = $this->checkProfileComplete($user);
        $token = $this->generateToken($user['id']);

        $this->json(['token' => $token, 'user' => [
            'id' => $user['id'],
            'username' => $user['username'],
            'email' => $user['email'],
            'link_slug' => $user['link_slug'],
            'is_seed' => $user['is_seed'],
            'is_profile_complete' => $isProfileComplete
        ]]);
    }

    public function logout() {
        // Client side just drops token, but we could blacklist it here if we had a blacklist table
        // For now, just set status offline
        // Requires Auth
        // For simplicity, we skip middleware check here in example but typically we'd use AuthMiddleware
        $this->json(['message' => 'Logged out']);
    }

    public function refresh() {
        // Implement refresh token logic if needed
        // For now, simple token regeneration
        $this->json(['message' => 'Not implemented yet'], 501);
    }

    private function checkProfileComplete($user) {
        return !empty($user['avatar_url']) && !empty($user['bio']) && !empty($user['gender']) && !empty($user['birth_date']);
    }

    private function generateToken($userId) {
        $payload = [
            'iss' => Env::get('JWT_ISSUER', 'anon-chat'),
            'sub' => $userId,
            'iat' => time(),
            'exp' => time() + (60 * 60 * 24 * 30) // 30 days
        ];
        return JWT::encode($payload, Env::get('JWT_SECRET'));
    }
}
