<?php

namespace Modules\Cancellation\Controllers;

use App\Controllers\BaseController;
use App\Libraries\Rolepermission;
use Modules\Cancellation\Models\GlobalCancellationModel;

class GlobalCancellation extends BaseController
{
    protected $Viewpath;
    protected $globalCancellationModel;
    protected $db;

    public function __construct()
    {
        $this->Viewpath = "Modules\Cancellation\Views";
        $this->globalCancellationModel = new GlobalCancellationModel();
        $this->db = \Config\Database::connect();
    }

    /**
     * Super admin (role 1) always allowed. Company accounts (role 7) never manage global policy. Others need manage_global_cancellation_policy.
     */
    private function assertCanAccessGlobalPolicy(bool $forWrite = false)
    {
        if ((int) $this->session->get('role_id') === 7) {
            return redirect()->route('admin-home')->with('fail', lang('Localize.global_cancellation_company_forbidden'));
        }

        if ((int) $this->session->get('role_id') === 1) {
            return null;
        }

        $perm = new Rolepermission();
        $allowed = $forWrite
            ? ($perm->edit('manage_global_cancellation_policy') || $perm->create('manage_global_cancellation_policy'))
            : $perm->read('manage_global_cancellation_policy');

        if (! $allowed) {
            return redirect()->route('admin-home')->with('fail', lang('Localize.global_cancellation_permission_required'));
        }

        return null;
    }

    public function index()
    {
        if ($deny = $this->assertCanAccessGlobalPolicy(false)) {
            return $deny;
        }

        $data['module'] = lang("Localize.global_cancellation_policy");
        $data['title']  = lang("Localize.global_cancellation_policy");
        $data['pageheading'] = lang("Localize.global_cancellation_policy");
        $data['menuname'] = "global-cancellations";
        
        // Fetch all global policies from the new dedicated table
        $data['cancellationlist'] = $this->globalCancellationModel->findAll();
        
        $data['list_available'] = count($data['cancellationlist']);
        $data['logged_user_id'] = $this->session->get('user_id');
        $data['role_id'] = $this->session->get('role_id');

        return view($this->Viewpath . '/global_cancellation/index', $data);
    }

    public function save()
    {
        if ($deny = $this->assertCanAccessGlobalPolicy(true)) {
            return $deny;
        }

        $hours = $this->request->getVar('hours');
        $charges = $this->request->getVar('charges');
        $userId = $this->session->get('user_id');
        
        if (!is_array($hours) || !is_array($charges)) {
            return redirect()->back()->withInput()->with('fail', 'Hours and charges must be arrays.');
        }

        if (count($hours) !== count($charges)) {
            return redirect()->back()->withInput()->with('fail', 'The number of hours and charges should be the same.');
        }

        if (empty($hours[0]) && count($hours) == 1) {
             return redirect()->back()->withInput()->with('fail', 'Please add at least 1 policy.');
        }

        // Custom validation
        $isValid = true;
        $errorMessages = [];
        $uniqueHours = [];

        foreach ($hours as $index => $hour) {
            $charge = $charges[$index];
            if ($hour !== "" && $charge !== "") {
                if (!is_numeric($hour) || (int)$hour != $hour) {
                    $isValid = false;
                    $errorMessages[] = "Row " . ($index + 1) . ": Hour value must be an integer.";
                }
                if (!is_numeric($charge) || $charge < 0 || $charge > 100) {
                    $isValid = false;
                    $errorMessages[] = "Row " . ($index + 1) . ": Charge must be a percentage (0-100).";
                }
                if (in_array($hour, $uniqueHours)) {
                    $isValid = false;
                    $errorMessages[] = "Row " . ($index + 1) . ": Hour value {$hour} is duplicated.";
                }
                $uniqueHours[] = $hour;
            }
        }

        if (!$isValid) {
            return redirect()->back()->withInput()->with('fail', implode('<br>', $errorMessages));
        }

        // Start transaction
        $this->db->transStart();

        // Truncate/Delete all from dedicated global table
        // (Using delete() instead of truncate to allow potential hooks or if table is small)
        $this->db->table('global_cancellation_policies')->where('deleted_at', NULL)->delete();
        // Since we use soft deletes in the model, we actually want to physically delete if we're replacing the whole set,
        // or just not use soft deletes for this specific table.
        // But to keep it simple and clean, let's just use the query builder to wipe it.
        $this->db->query("DELETE FROM global_cancellation_policies");

        // Insert new policies
        foreach ($hours as $index => $hour) {
            if ($hour !== "" && $charges[$index] !== "") {
                $this->globalCancellationModel->insert([
                    "user_id" => $userId,
                    "hours" => $hour,
                    "charges" => $charges[$index],
                ]);
            }
        }

        $this->db->transComplete();

        if ($this->db->transStatus() === false) {
            return redirect()->back()->with('fail', 'Something went wrong while saving the data.');
        } else {
            return redirect()->route('index-global-cancellation')->with('success', 'Global cancellation policy saved successfully.');
        }
    }
}
