<?php
require_once 'config/database.php';

class UsersController
{
    private $conn;

    public function __construct()
    {
        $database = new Database();
        $this->conn = $database->getConnection();
    }

    public function createUser($data)
    {
        if (!isset($data['first_name'], $data['last_name'], $data['email'], $data['phone'], $data['nin'], $data['role_id'], $data['password'])) {
            return json_encode(['status' => 'error', 'message' => 'Missing required fields']);
        }

        $query = "SELECT id FROM users WHERE email = :email";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':email', $data['email']);
        $stmt->execute();
        if ($stmt->rowCount() > 0) {
            return json_encode(['status' => 'error', 'message' => 'Email already exists']);
        }

        $password_hash = password_hash($data['password'], PASSWORD_DEFAULT);

        $query = "INSERT INTO users (first_name, last_name, email, phone, nin, role_id, supervisor_id, password_hash, status, permissions) VALUES (:first_name, :last_name, :email, :phone, :nin, :role_id, :supervisor_id, :password_hash, :status, :permissions)";
        $stmt = $this->conn->prepare($query);
        $status = 'active';
        $supervisor_id = $data['supervisor_id'] ?? null;
        $permissions = (array_key_exists('permissions', $data) && is_array($data['permissions']))
            ? json_encode(array_values($data['permissions']))
            : null;
        $stmt->bindParam(':first_name', $data['first_name']);
        $stmt->bindParam(':last_name', $data['last_name']);
        $stmt->bindParam(':email', $data['email']);
        $stmt->bindParam(':phone', $data['phone']);
        $stmt->bindParam(':nin', $data['nin']);
        $stmt->bindParam(':role_id', $data['role_id']);
        $stmt->bindParam(':supervisor_id', $supervisor_id);
        $stmt->bindParam(':password_hash', $password_hash);
        $stmt->bindParam(':status', $status);
        $stmt->bindParam(':permissions', $permissions);

        if ($stmt->execute()) {
            return json_encode(['status' => 'success', 'message' => 'User created successfully', 'data' => ['user_id' => $this->conn->lastInsertId()]]);
        } else {
            return json_encode(['status' => 'error', 'message' => 'Error creating user']);
        }
    }

    public function getAllUsers($filters)
    {
        try {
            $limit = isset($filters['limit']) ? (int)$filters['limit'] : 10;
            $offset = isset($filters['offset']) ? (int)$filters['offset'] : 0;

            $query = "SELECT u.id, u.first_name, u.last_name, u.email, u.phone, u.nin, u.profile_photo, u.status, u.role_id, u.last_login, u.permissions, r.name as role, s.id as supervisor_id, CONCAT(s.first_name, ' ', s.last_name) as supervisor_name
                    FROM users u
                    JOIN roles r ON u.role_id = r.id
                    LEFT JOIN users s ON u.supervisor_id = s.id
                    WHERE 1=1";

            $params = [];

            // Filter by role
            if (!empty($filters['role_id'])) {
                $query .= " AND u.role_id = :role_id";
                $params[':role_id'] = $filters['role_id'];
            }

            // Optional search (by name or email)
            if (!empty($filters['search'])) {
                $query .= " AND (u.first_name LIKE :search OR u.last_name LIKE :search OR u.email LIKE :search)";
                $params[':search'] = "%" . $filters['search'] . "%";
            }

            $query .= " LIMIT :limit OFFSET :offset";

            $stmt = $this->conn->prepare($query);

            // Bind role_id
            if (!empty($filters['role_id'])) {
                $stmt->bindValue(':role_id', $filters['role_id'], PDO::PARAM_INT);
            }

            // Bind search
            if (!empty($filters['search'])) {
                $stmt->bindValue(':search', "%" . $filters['search'] . "%", PDO::PARAM_STR);
            }

            // Bind limit/offset as integers
            $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
            $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);

            $stmt->execute();
            $users = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Decode per-user permissions JSON to an array (null stays null → client uses role defaults)
            foreach ($users as &$u) {
                $u['permissions'] = ($u['permissions'] !== null && $u['permissions'] !== '')
                    ? json_decode($u['permissions'], true)
                    : null;
            }
            unset($u);

            // Count query
            $count_query = "SELECT COUNT(*) as total FROM users WHERE 1=1";
            $count_params = [];

            if (!empty($filters['role_id'])) {
                $count_query .= " AND role_id = :role_id";
                $count_params[':role_id'] = $filters['role_id'];
            }

            if (!empty($filters['search'])) {
                $count_query .= " AND (first_name LIKE :search OR last_name LIKE :search OR email LIKE :search)";
                $count_params[':search'] = "%" . $filters['search'] . "%";
            }

            $stmt_count = $this->conn->prepare($count_query);

            if (!empty($filters['role_id'])) {
                $stmt_count->bindValue(':role_id', $filters['role_id'], PDO::PARAM_INT);
            }
            if (!empty($filters['search'])) {
                $stmt_count->bindValue(':search', "%" . $filters['search'] . "%", PDO::PARAM_STR);
            }

            $stmt_count->execute();
            $totalRecords = $stmt_count->fetch(PDO::FETCH_ASSOC)['total'];

            $totalPages = $totalRecords > 0 ? ceil($totalRecords / $limit) : 1;

            return json_encode([
                'status' => 'success',
                'data' => [
                    'users' => $users,
                    'pagination' => [
                        'current_page' => isset($filters['page']) ? (int)$filters['page'] : 1,
                        'total_pages' => $totalPages,
                        'total_records' => $totalRecords,
                    ]
                ]
            ]);
        } catch (PDOException $e) {
            return json_encode([
                'status' => 'error',
                'message' => 'Database error: ' . $e->getMessage()
            ]);
        } catch (Exception $e) {
            return json_encode([
                'status' => 'error',
                'message' => 'Unexpected error: ' . $e->getMessage()
            ]);
        }
    }

    public function getUserById($id)
    {
        $query = "SELECT u.id, u.first_name, u.last_name, u.email, u.phone, u.nin, u.profile_photo, u.status, u.role_id, u.permissions, r.name as role, s.id as supervisor_id, CONCAT(s.first_name, ' ', s.last_name) as supervisor_name, u.email_notifications, u.sms_notifications, u.push_notifications, u.escalation_alerts, u.performance_reports
            FROM users u
            JOIN roles r ON u.role_id = r.id
            LEFT JOIN users s ON u.supervisor_id = s.id
            WHERE u.id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->execute([':id' => $id]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user) {
            $user['permissions'] = ($user['permissions'] !== null && $user['permissions'] !== '')
                ? json_decode($user['permissions'], true)
                : null;
            return json_encode([
                'status' => 'success',
                'data' => $user
            ]);
        } else {
            return json_encode(['status' => 'error', 'message' => 'User not found']);
        }
    }


    public function updateUser($data)
    {
        if (!isset($data['id'], $data['first_name'], $data['last_name'], $data['email'], $data['phone'], $data['nin'], $data['role_id'])) {
            return json_encode(['status' => 'error', 'message' => 'Missing required fields']);
        }

        $query = "SELECT id FROM users WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':id', $data['id']);
        $stmt->execute();
        if ($stmt->rowCount() === 0) {
            return json_encode(['status' => 'error', 'message' => 'User not found']);
        }

        // Optionally update the per-user permissions (JSON array of keys).
        $permsProvided = array_key_exists('permissions', $data) && is_array($data['permissions']);
        $permsJson = $permsProvided ? json_encode(array_values($data['permissions'])) : null;

        $query = "UPDATE users SET first_name = :first_name, last_name = :last_name, email = :email, phone = :phone, nin = :nin, role_id = :role_id, supervisor_id = :supervisor_id"
            . ($permsProvided ? ", permissions = :permissions" : "")
            . ", updated_at = NOW() WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $supervisor_id = $data['supervisor_id'] ?? null;
        $stmt->bindParam(':first_name', $data['first_name']);
        $stmt->bindParam(':last_name', $data['last_name']);
        $stmt->bindParam(':email', $data['email']);
        $stmt->bindParam(':phone', $data['phone']);
        $stmt->bindParam(':nin', $data['nin']);
        $stmt->bindParam(':role_id', $data['role_id']);
        $stmt->bindParam(':supervisor_id', $supervisor_id);
        if ($permsProvided) $stmt->bindParam(':permissions', $permsJson);
        $stmt->bindParam(':id', $data['id']);

        if ($stmt->execute()) {
            return json_encode(['status' => 'success', 'message' => 'User updated successfully']);
        } else {
            return json_encode(['status' => 'error', 'message' => 'Error updating user']);
        }
    }

    public function toggleUserStatus($data)
    {
        if (!isset($data['id'])) {
            return json_encode(['status' => 'error', 'message' => 'Missing required field: id']);
        }

        $query = "SELECT status FROM users WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':id', $data['id']);
        $stmt->execute();
        if ($stmt->rowCount() === 0) {
            return json_encode(['status' => 'error', 'message' => 'User not found']);
        }

        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        $newStatus = ($user['status'] === 'active') ? 'inactive' : 'active';

        $query = "UPDATE users SET status = :status, updated_at = NOW() WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':status', $newStatus);
        $stmt->bindParam(':id', $data['id']);

        if ($stmt->execute()) {
            return json_encode(['status' => 'success', 'message' => 'User status updated successfully']);
        } else {
            return json_encode(['status' => 'error', 'message' => 'Error updating user status']);
        }
    }

    public function getUsersStatistics()
    {
        try {
            $query = "SELECT 
                (SELECT COUNT(*) FROM users) as all_users,
                (SELECT COUNT(*) FROM users WHERE role_id = 1) as administrators,
                (SELECT COUNT(*) FROM users WHERE role_id = 2) as supervisors,
                (SELECT COUNT(*) FROM users WHERE role_id = 3) as ipos";
            $stmt = $this->conn->prepare($query);
            $stmt->execute();
            $stats = $stmt->fetch(PDO::FETCH_ASSOC);

            return json_encode([
                'status' => 'success',
                'data' => [
                    'all' => (int)$stats['all_users'],
                    'administrator' => (int)$stats['administrators'],
                    'supervisor' => (int)$stats['supervisors'],
                    'ipo' => (int)$stats['ipos']
                ]
            ]);
        } catch (PDOException $e) {
            return json_encode([
                'status' => 'error',
                'message' => 'Database error: ' . $e->getMessage()
            ]);
        } catch (Exception $e) {
            return json_encode([
                'status' => 'error',
                'message' => 'Unexpected error: ' . $e->getMessage()
            ]);
        }
    }

    // REPLACE THESE TWO METHODS IN SettingsController

    public function updateNotifications($data, $userId)
    {
        $fields = [
            'email_notifications' => $data['email_notifications'] ?? 1,
            'sms_notifications' => $data['sms_notifications'] ?? 0,
            'push_notifications' => $data['push_notifications'] ?? 1,
            'escalation_alerts' => $data['escalation_alerts'] ?? 1,
            'performance_reports' => $data['performance_reports'] ?? 1
        ];

        $set = '';
        $params = [':id' => $userId];
        foreach ($fields as $col => $val) {
            $set .= "$col = :$col, ";
            $params[":$col"] = $val ? 1 : 0;
        }
        $set = rtrim($set, ', ');

        $query = "UPDATE users SET $set WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->execute($params);

        return json_encode(['status' => 'success', 'message' => 'Notification preferences updated successfully']);
    }

    public function getNotifications($userId)
    {
        $query = "SELECT 
        email_notifications,
        sms_notifications,
        push_notifications,
        escalation_alerts,
        performance_reports
        FROM users WHERE id = :id";

        $stmt = $this->conn->prepare($query);
        $stmt->execute([':id' => $userId]);
        $prefs = $stmt->fetch(PDO::FETCH_ASSOC);

        // Convert TINYINT to boolean
        foreach ($prefs as $key => $value) {
            $prefs[$key] = (bool)$value;
        }

        return json_encode(['status' => 'success', 'data' => $prefs]);
    }
}
