<?php

namespace App\Controllers;

use App\Models\KategoriModel;
use Config\Database;

class KategoriController extends BaseController
{
    private KategoriModel $kategoriModel;

    public function __construct()
    {
        $this->kategoriModel = new KategoriModel();
    }

    public function index()
    {
        if (! $this->isLoggedIn()) {
            return redirect()->to('/login')->with('error', 'Silakan login terlebih dahulu.');
        }

        if ($redirect = $this->requireAdministrator('/admin/dashboard', 'Akses ditolak. Data kategori hanya dapat diakses oleh administrator.')) {
            return $redirect;
        }

        $kategori = $this->kategoriModel
            ->select('kategori.*')
            ->select('(SELECT COUNT(*) FROM barang WHERE barang.kategori_id = kategori.id) AS total_barang', false)
            ->orderBy('id', 'DESC')
            ->findAll();

        return view('admin/kategori/index', [
            'kategori'  => $kategori,
            'userName'  => session()->get('userName'),
            'userEmail' => session()->get('userEmail'),
            'userRole'  => session()->get('userRole'),
        ]);
    }

    public function create()
    {
        if (! $this->isLoggedIn()) {
            return redirect()->to('/login')->with('error', 'Silakan login terlebih dahulu.');
        }

        if ($redirect = $this->requireAdministrator('/admin/kategori')) {
            return $redirect;
        }

        return view('admin/kategori/create', [
            'userName'  => session()->get('userName'),
            'userEmail' => session()->get('userEmail'),
            'userRole'  => session()->get('userRole'),
        ]);
    }

    public function store()
    {
        if (! $this->isLoggedIn()) {
            return redirect()->to('/login')->with('error', 'Silakan login terlebih dahulu.');
        }

        if ($redirect = $this->requireAdministrator('/admin/kategori')) {
            return $redirect;
        }

        $rules = [
            'nama_kategori' => 'required|min_length[2]|max_length[100]|is_unique[kategori.nama_kategori]',
            'icon_kategori' => 'required|max_length[80]|regex_match[/^bi-[a-z0-9-]+$/]',
        ];

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

        $this->kategoriModel->insert([
            'nama_kategori' => $this->request->getPost('nama_kategori'),
            'icon_kategori' => $this->request->getPost('icon_kategori'),
        ]);

        return redirect()->to('/admin/kategori')->with('success', 'Data kategori berhasil ditambahkan.');
    }

    public function edit(int $id)
    {
        if (! $this->isLoggedIn()) {
            return redirect()->to('/login')->with('error', 'Silakan login terlebih dahulu.');
        }

        if ($redirect = $this->requireAdministrator('/admin/kategori')) {
            return $redirect;
        }

        $kategori = $this->kategoriModel->find($id);

        if (! $kategori) {
            return redirect()->to('/admin/kategori')->with('error', 'Data kategori tidak ditemukan.');
        }

        return view('admin/kategori/edit', [
            'kategori'  => $kategori,
            'userName'  => session()->get('userName'),
            'userEmail' => session()->get('userEmail'),
            'userRole'  => session()->get('userRole'),
        ]);
    }

    public function update(int $id)
    {
        if (! $this->isLoggedIn()) {
            return redirect()->to('/login')->with('error', 'Silakan login terlebih dahulu.');
        }

        if ($redirect = $this->requireAdministrator('/admin/kategori')) {
            return $redirect;
        }

        $kategori = $this->kategoriModel->find($id);

        if (! $kategori) {
            return redirect()->to('/admin/kategori')->with('error', 'Data kategori tidak ditemukan.');
        }

        $rules = [
            'nama_kategori' => 'required|min_length[2]|max_length[100]|is_unique[kategori.nama_kategori,id,' . $id . ']',
            'icon_kategori' => 'required|max_length[80]|regex_match[/^bi-[a-z0-9-]+$/]',
        ];

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

        $this->kategoriModel->update($id, [
            'nama_kategori' => $this->request->getPost('nama_kategori'),
            'icon_kategori' => $this->request->getPost('icon_kategori'),
        ]);

        return redirect()->to('/admin/kategori')->with('success', 'Data kategori berhasil diperbarui.');
    }

    public function delete(int $id)
    {
        if (! $this->isLoggedIn()) {
            return redirect()->to('/login')->with('error', 'Silakan login terlebih dahulu.');
        }

        if ($redirect = $this->requireAdministrator('/admin/kategori')) {
            return $redirect;
        }

        $kategori = $this->kategoriModel->find($id);

        if (! $kategori) {
            return redirect()->to('/admin/kategori')->with('error', 'Data kategori tidak ditemukan.');
        }

        if ($this->totalBarangByKategori($id) > 0) {
            return redirect()->to('/admin/kategori')->with(
                'error',
                'Data kategori tidak dapat dihapus karena sudah terhubung ke data barang.'
            );
        }

        $this->kategoriModel->delete($id);

        return redirect()->to('/admin/kategori')->with('success', 'Data kategori berhasil dihapus.');
    }

    private function totalBarangByKategori(int $kategoriId): int
    {
        return Database::connect()
            ->table('barang')
            ->where('kategori_id', $kategoriId)
            ->countAllResults();
    }

    private function isLoggedIn(): bool
    {
        return (bool) session()->get('isLoggedIn') && $this->isUserAccount();
    }
}
