<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class User_model extends CI_Model {

    protected $table = 'users';

    public function __construct() {
        parent::__construct();
    }

    /**
     * Get user by ID
     */
    public function get($id) {
        return $this->db->get_where($this->table, ['id' => $id])->row();
    }

    /**
     * Get user by UUID
     */
    public function get_by_uuid($uuid) {
        return $this->db->get_where($this->table, ['uuid' => $uuid])->row();
    }

    /**
     * Get user by email
     */
    public function get_by_email($email) {
        return $this->db->get_where($this->table, ['email' => $email])->row();
    }

    /**
     * Get user by phone
     */
    public function get_by_phone($phone) {
        return $this->db->get_where($this->table, ['phone' => $phone])->row();
    }

    /**
     * Get all users with optional filters
     */
    public function get_all($filters = [], $limit = null, $offset = 0) {
        if (!empty($filters['user_type'])) {
            $this->db->where('user_type', $filters['user_type']);
        }
        if (!empty($filters['status'])) {
            $this->db->where('status', $filters['status']);
        }
        if (!empty($filters['search'])) {
            $this->db->group_start();
            $this->db->like('first_name', $filters['search']);
            $this->db->or_like('last_name', $filters['search']);
            $this->db->or_like('email', $filters['search']);
            $this->db->or_like('phone', $filters['search']);
            $this->db->group_end();
        }
        
        $this->db->order_by('created_at', 'DESC');
        
        if ($limit) {
            $this->db->limit($limit, $offset);
        }
        
        return $this->db->get($this->table)->result();
    }

    /**
     * Count all users with optional filters
     */
    public function count_all($filters = []) {
        if (!empty($filters['user_type'])) {
            $this->db->where('user_type', $filters['user_type']);
        }
        if (!empty($filters['status'])) {
            $this->db->where('status', $filters['status']);
        }
        
        return $this->db->count_all_results($this->table);
    }

    /**
     * Create new user
     */
    public function create($data) {
        $data['uuid'] = $this->generate_uuid();
        $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
        $data['created_at'] = date('Y-m-d H:i:s');
        
        if (isset($data['pin']) && !empty($data['pin'])) {
            $data['pin'] = password_hash($data['pin'], PASSWORD_DEFAULT);
        }
        
        $this->db->insert($this->table, $data);
        return $this->db->insert_id();
    }

    /**
     * Update user
     */
    public function update($id, $data) {
        $data['updated_at'] = date('Y-m-d H:i:s');
        
        if (isset($data['password']) && !empty($data['password'])) {
            $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
        } else {
            unset($data['password']);
        }
        
        if (isset($data['pin']) && !empty($data['pin'])) {
            $data['pin'] = password_hash($data['pin'], PASSWORD_DEFAULT);
        } else {
            unset($data['pin']);
        }
        
        return $this->db->update($this->table, $data, ['id' => $id]);
    }

    /**
     * Delete user
     */
    public function delete($id) {
        return $this->db->delete($this->table, ['id' => $id]);
    }

    /**
     * Verify password
     */
    public function verify_password($user_id, $password) {
        $user = $this->get($user_id);
        if ($user) {
            return password_verify($password, $user->password);
        }
        return false;
    }

    /**
     * Verify transaction PIN
     */
    public function verify_pin($user_id, $pin) {
        $user = $this->get($user_id);
        if ($user && $user->pin) {
            return password_verify($pin, $user->pin);
        }
        return false;
    }

    /**
     * Update last login
     */
    public function update_last_login($id, $ip_address) {
        return $this->db->update($this->table, [
            'last_login_at' => date('Y-m-d H:i:s'),
            'last_login_ip' => $ip_address
        ], ['id' => $id]);
    }

    /**
     * Update user status
     */
    public function update_status($id, $status) {
        return $this->db->update($this->table, [
            'status' => $status,
            'updated_at' => date('Y-m-d H:i:s')
        ], ['id' => $id]);
    }

    /**
     * Get user with KYC info
     */
    public function get_with_kyc($id) {
        $this->db->select('users.*, kyc.tier, kyc.bvn, kyc.nin, kyc.verification_status as kyc_status');
        $this->db->from($this->table);
        $this->db->join('kyc', 'kyc.user_id = users.id', 'left');
        $this->db->where('users.id', $id);
        return $this->db->get()->row();
    }

    /**
     * Generate UUID v4
     */
    private function generate_uuid() {
        $data = random_bytes(16);
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }

    /**
     * Check if email exists
     */
    public function email_exists($email, $exclude_id = null) {
        $this->db->where('email', $email);
        if ($exclude_id) {
            $this->db->where('id !=', $exclude_id);
        }
        return $this->db->count_all_results($this->table) > 0;
    }

    /**
     * Check if phone exists
     */
    public function phone_exists($phone, $exclude_id = null) {
        $this->db->where('phone', $phone);
        if ($exclude_id) {
            $this->db->where('id !=', $exclude_id);
        }
        return $this->db->count_all_results($this->table) > 0;
    }

    /**
     * Log login attempt
     */
    public function log_login_attempt($email, $ip_address, $user_agent, $success) {
        return $this->db->insert('login_attempts', [
            'email' => $email,
            'ip_address' => $ip_address,
            'user_agent' => $user_agent,
            'success' => $success ? 1 : 0,
            'created_at' => date('Y-m-d H:i:s')
        ]);
    }

    /**
     * Count recent failed login attempts
     */
    public function count_failed_attempts($email, $minutes = 30) {
        $time_limit = date('Y-m-d H:i:s', strtotime("-{$minutes} minutes"));
        $this->db->where('email', $email);
        $this->db->where('success', 0);
        $this->db->where('created_at >=', $time_limit);
        return $this->db->count_all_results('login_attempts');
    }
}
