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

class User_model extends CI_Model {

    public function __construct() {
        parent::__construct();
        $this->load->database(); // default = hsidb
    }

    /* ===========================
     * AUTH
     * =========================== */

    /** Login siswa (by Email/Phone + role name = 'Siswa') */
    public function login($identity, $password, $roleName = 'Siswa') {
        $user = $this->db->select('u.*, r.RoleName')
            ->from('users u')
            ->join('roles r', 'r.RoleID = u.RoleID', 'inner')
            ->group_start()
                ->where('u.Email', $identity)
                ->or_where('u.Phone', $identity)
            ->group_end()
            ->where('r.RoleName', $roleName)
            ->get()->row();

        if (!$user) return false;

        // transisi: cek plain terlebih dulu (kalau masih disimpan)
        if (!empty($user->Password) && hash_equals((string)$user->Password, (string)$password)) {
            return $user;
        }
        // prefer hash
        if (!empty($user->PasswordHash) && password_verify($password, $user->PasswordHash)) {
            return $user;
        }
        return false;
    }

    /** Login admin (role 1/2) */
    public function login_admin($identity, $password) {
        $user = $this->db->select('u.*, r.RoleName')
            ->from('users u')
            ->join('roles r', 'u.RoleID = r.RoleID', 'left')
            ->group_start()
                ->where('u.Email', $identity)
                ->or_where('u.Phone', $identity)
            ->group_end()
            ->where_in('u.RoleID', [1,2])
            ->get()->row();

        if (!$user) return false;

        if (!empty($user->Password) && hash_equals((string)$user->Password, (string)$password)) {
            return $user;
        }
        if (!empty($user->PasswordHash) && password_verify($password, $user->PasswordHash)) {
            return $user;
        }
        return false;
    }

    /* ===========================
     * CRUD USER
     * =========================== */

    /** Buat user baru */
    public function create_user(array $data) {
        // whitelist kolom users
        $row = [
            'Username'  => $data['Username'] ?? null,
            'Email'     => $data['Email']    ?? null,
            'Phone'     => $data['Phone']    ?? null,
            'RoleID'    => isset($data['RoleID']) ? (int)$data['RoleID'] : 3,
            'CreatedAt' => $data['CreatedAt'] ?? date('Y-m-d H:i:s'),
        ];

        if (!empty($data['PasswordPlain'])) {
            $plain               = (string)$data['PasswordPlain'];
            $row['Password']     = $plain; // sementara masih disimpan (sesuai kode eksisting)
            $row['PasswordHash'] = password_hash($plain, PASSWORD_DEFAULT);
        } elseif (!empty($data['Password'])) {
            $row['Password']     = (string)$data['Password'];
            $row['PasswordHash'] = password_hash((string)$data['Password'], PASSWORD_DEFAULT);
        }

        $ok = $this->db->insert('users', $row);
        if (!$ok) {
            $err = $this->db->error(); // ['code'], ['message']
            log_message('error', 'create_user failed: '.$err['code'].' '.$err['message']);
            return false;
        }
        return (int)$this->db->insert_id();
    }

    public function get_user_by_id($user_id) {
        return $this->db->get_where('users', ['UserID' => (int)$user_id])->row();
    }

    public function get_by_id($user_id) {
        return $this->get_user_by_id($user_id);
    }

    public function get_all_users() {
        return $this->db->get('users')->result();
    }

    public function update_user($user_id, array $data) {
        $row = [];
        foreach (['Username','Email','Phone','RoleID','SiswaID','CreatedAt'] as $k) {
            if (array_key_exists($k, $data)) $row[$k] = $data[$k];
        }
        if (!empty($data['PasswordPlain'])) {
            $plain               = (string)$data['PasswordPlain'];
            $row['Password']     = $plain;
            $row['PasswordHash'] = password_hash($plain, PASSWORD_DEFAULT);
        }
        $this->db->where('UserID', (int)$user_id);
        $ok = $this->db->update('users', $row);
        if (!$ok) {
            $err = $this->db->error();
            log_message('error', 'update_user failed: '.$err['code'].' '.$err['message']);
        }
        return $ok;
    }

    public function delete_user($user_id) {
        return $this->db->delete('users', ['UserID' => (int)$user_id]);
    }

    /* ===========================
     * SISWA RELATED
     * =========================== */

    /** Ambil user + siswa (left join) */
    public function get_user_with_siswa($user_id) {
        return $this->db
            ->select('u.UserID, u.Username, u.Email, u.Phone, u.CreatedAt, s.SiswaID, s.NamaLengkap, ss.NamaStatus')
            ->from('users u')
            ->join('siswa s', 'u.UserID = s.UserID', 'left')
            ->join('statussiswa ss', 's.StatusID = ss.StatusID', 'left')
            ->where('u.UserID', (int)$user_id)
            ->get()->row();
    }

    /** Generate SiswaID: HSIYYYYMM-#### (ambil urutan dari tabel siswa) */
    public function generate_siswa_id() {
        $prefix = 'HSI'.date('Ym').'-';
        $last = $this->db->select('SiswaID')
            ->like('SiswaID', $prefix, 'after')
            ->order_by('SiswaID', 'DESC')->limit(1)
            ->get('siswa')->row();

        $seq = 1;
        if ($last && preg_match('/-(\d{4})$/', $last->SiswaID, $m)) {
            $seq = (int)$m[1] + 1;
        }
        return $prefix . str_pad($seq, 4, '0', STR_PAD_LEFT);
    }

    /** Assign SiswaID ke user dan tabel siswa */
    public function assign_siswa_id($user_id) {
        $new_id = $this->generate_siswa_id();
        $this->db->where('UserID', (int)$user_id)->update('siswa', ['SiswaID' => $new_id]);
        $this->db->where('UserID', (int)$user_id)->update('users', ['SiswaID' => $new_id]); // kalau kolom ini dipakai
        return $new_id;
    }
}
