<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\ViolationCategoryModel;
use App\Models\ViolationRuleModel;
use App\Models\ViolationSanctionModel;

class ViolationSettings extends BaseController
{
    protected $categoryModel;
    protected $ruleModel;
    protected $sanctionModel;

    public function __construct()
    {
        $this->categoryModel = new ViolationCategoryModel();
        $this->ruleModel     = new ViolationRuleModel();
        $this->sanctionModel = new ViolationSanctionModel();
    }

    private function checkAccess()
    {
        $role = session()->get('user_role');
        if (!in_array($role, ['superadmin', 'admin', 'guru'])) {
            return false;
        }
        return true;
    }

    public function index()
    {
        if (!$this->checkAccess()) {
            return redirect()->to('/login')->with('error', 'Akses ditolak.');
        }

        $data = [
            'title'      => 'Pengaturan Poin Pelanggaran',
            'categories' => $this->categoryModel->orderBy('name', 'ASC')->findAll(),
            'rules'      => $this->ruleModel->getAllWithCategory(),
            'sanctions'  => $this->sanctionModel->orderBy('min_points', 'ASC')->findAll(),
        ];

        return view('settings/violation_settings', $data);
    }

    // ── KATEGORI CRUD ───────────────────────────────────────────────
    public function storeCategory()
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $name = trim($this->request->getPost('name') ?? '');
        if (empty($name)) {
            return redirect()->back()->with('error', 'Nama kategori tidak boleh kosong.');
        }

        $this->categoryModel->insert(['name' => $name]);
        return redirect()->to('/violation-settings')->with('success', 'Kategori berhasil ditambahkan!');
    }

    public function updateCategory($id)
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $name = trim($this->request->getPost('name') ?? '');
        if (empty($name)) {
            return redirect()->back()->with('error', 'Nama kategori tidak boleh kosong.');
        }

        $this->categoryModel->update($id, ['name' => $name]);
        return redirect()->to('/violation-settings')->with('success', 'Kategori berhasil diperbarui!');
    }

    public function deleteCategory($id)
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        // Cek jika kategori ini sedang digunakan di rules
        $rulesCount = $this->ruleModel->where('category_id', $id)->countAllResults();
        if ($rulesCount > 0) {
            return redirect()->to('/violation-settings')->with('error', 'Kategori tidak dapat dihapus karena masih digunakan oleh beberapa aturan pelanggaran.');
        }

        $this->categoryModel->delete($id);
        return redirect()->to('/violation-settings')->with('success', 'Kategori berhasil dihapus!');
    }

    // ── ATURAN POIN CRUD ────────────────────────────────────────────
    public function storeRule()
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $rules = [
            'category_id' => 'required|is_natural_no_zero',
            'code'        => 'required|min_length[3]|max_length[20]',
            'description' => 'required|min_length[3]|max_length[255]',
            'severity'    => 'required|in_list[Ringan,Sedang,Berat,Khusus]',
            'points'      => 'required|is_natural_no_zero',
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->with('errors', $this->validator->getErrors())->withInput();
        }

        // Cek duplikasi kode
        $code = trim($this->request->getPost('code') ?? '');
        $exists = $this->ruleModel->where('code', $code)->first();
        if ($exists) {
            return redirect()->back()->with('error', 'Kode pelanggaran "' . $code . '" sudah digunakan.')->withInput();
        }

        $this->ruleModel->insert([
            'category_id' => $this->request->getPost('category_id'),
            'code'        => $code,
            'description' => trim($this->request->getPost('description') ?? ''),
            'severity'    => $this->request->getPost('severity'),
            'points'      => $this->request->getPost('points'),
        ]);

        return redirect()->to('/violation-settings')->with('success', 'Aturan pelanggaran berhasil ditambahkan!');
    }

    public function updateRule($id)
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $rules = [
            'category_id' => 'required|is_natural_no_zero',
            'code'        => 'required|min_length[3]|max_length[20]',
            'description' => 'required|min_length[3]|max_length[255]',
            'severity'    => 'required|in_list[Ringan,Sedang,Berat,Khusus]',
            'points'      => 'required|is_natural_no_zero',
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->with('errors', $this->validator->getErrors())->withInput();
        }

        // Cek duplikasi kode dengan ID lain
        $code = trim($this->request->getPost('code') ?? '');
        $exists = $this->ruleModel->where('code', $code)->where('id !=', $id)->first();
        if ($exists) {
            return redirect()->back()->with('error', 'Kode pelanggaran "' . $code . '" sudah digunakan oleh aturan lain.')->withInput();
        }

        $this->ruleModel->update($id, [
            'category_id' => $this->request->getPost('category_id'),
            'code'        => $code,
            'description' => trim($this->request->getPost('description') ?? ''),
            'severity'    => $this->request->getPost('severity'),
            'points'      => $this->request->getPost('points'),
        ]);

        return redirect()->to('/violation-settings')->with('success', 'Aturan pelanggaran berhasil diperbarui!');
    }

    public function deleteRule($id)
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $db = \Config\Database::connect();
        $inUse = $db->table('student_violations')->where('rule_id', $id)->countAllResults();
        if ($inUse > 0) {
            return redirect()->to('/violation-settings')->with('error', 'Aturan tidak dapat dihapus karena telah terdata pada beberapa riwayat pelanggaran siswa.');
        }

        $this->ruleModel->delete($id);
        return redirect()->to('/violation-settings')->with('success', 'Aturan pelanggaran berhasil dihapus!');
    }

    // ── AMBANG BATAS SANKSI CRUD ────────────────────────────────────
    public function storeSanction()
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $rules = [
            'min_points'   => 'required|is_natural_no_zero',
            'action_title' => 'required|min_length[3]|max_length[150]',
            'description'  => 'required|min_length[5]',
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->with('errors', $this->validator->getErrors())->withInput();
        }

        // Cek duplikasi poin
        $minPoints = $this->request->getPost('min_points');
        $exists = $this->sanctionModel->where('min_points', $minPoints)->first();
        if ($exists) {
            return redirect()->back()->with('error', 'Ambang batas sanksi untuk ' . $minPoints . ' poin sudah ada.')->withInput();
        }

        $this->sanctionModel->insert([
            'min_points'   => $minPoints,
            'action_title' => trim($this->request->getPost('action_title') ?? ''),
            'description'  => trim($this->request->getPost('description') ?? ''),
        ]);

        return redirect()->to('/violation-settings')->with('success', 'Ambang batas sanksi berhasil ditambahkan!');
    }

    public function updateSanction($id)
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $rules = [
            'min_points'   => 'required|is_natural_no_zero',
            'action_title' => 'required|min_length[3]|max_length[150]',
            'description'  => 'required|min_length[5]',
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->with('errors', $this->validator->getErrors())->withInput();
        }

        $minPoints = $this->request->getPost('min_points');
        $exists = $this->sanctionModel->where('min_points', $minPoints)->where('id !=', $id)->first();
        if ($exists) {
            return redirect()->back()->with('error', 'Ambang batas sanksi untuk ' . $minPoints . ' poin sudah digunakan sanksi lain.')->withInput();
        }

        $this->sanctionModel->update($id, [
            'min_points'   => $minPoints,
            'action_title' => trim($this->request->getPost('action_title') ?? ''),
            'description'  => trim($this->request->getPost('description') ?? ''),
        ]);

        return redirect()->to('/violation-settings')->with('success', 'Ambang batas sanksi berhasil diperbarui!');
    }

    public function deleteSanction($id)
    {
        if (!$this->checkAccess()) return redirect()->back()->with('error', 'Akses ditolak.');

        $this->sanctionModel->delete($id);
        return redirect()->to('/violation-settings')->with('success', 'Ambang batas sanksi berhasil dihapus!');
    }
}
