<?php
namespace App\Controllers;

use App\Core\Auth;
use App\Core\Controller;
use App\Core\Database;
use App\Core\Request;
use App\Core\Session;
use App\Services\SlaEngine;
use DateTime;

class SlaController extends Controller
{
    public function __construct()
    {
        if (!Auth::can('sla.configure')) {
            http_response_code(403);
            echo '<!doctype html><body style="font-family:sans-serif;padding:40px"><h1>403</h1><p>You do not have permission to configure SLA policies.</p></body>';
            exit;
        }
    }

    public function index(): void
    {
        $policies = Database::all('SELECT p.*, c.name AS calendar_name FROM sla_policies p JOIN business_calendars c ON c.id = p.calendar_id ORDER BY p.contract_tier, p.version DESC');
        $this->render('sla/index', ['pageTitle' => 'SLA Policies', 'policies' => $policies]);
    }

    public function createForm(): void
    {
        $this->render('sla/edit', [
            'pageTitle' => 'New SLA policy', 'policy' => null, 'targets' => [], 'levels' => [],
            'calendars' => Database::all('SELECT * FROM business_calendars ORDER BY name'),
            'products' => Database::all('SELECT * FROM products WHERE is_active = 1 ORDER BY name'),
            'priorities' => Database::all('SELECT * FROM priorities WHERE is_active = 1 ORDER BY sort_order'),
        ]);
    }

    public function store(): void
    {
        $this->requireCsrf();
        $id = Database::insert('sla_policies', [
            'name' => Request::post('name'), 'contract_tier' => Request::post('contract_tier') ?: null,
            'product_id' => Request::post('product_id') ?: null, 'calendar_id' => Request::post('calendar_id'),
            'is_24x7' => Request::post('is_24x7') ? 1 : 0, 'effective_from' => Request::post('effective_from', date('Y-m-d')),
        ]);
        $this->saveTargets($id);
        Session::flash('success', 'SLA policy created.');
        $this->redirect('/admin/sla/' . $id);
    }

    public function edit(string $id): void
    {
        $policy = Database::one('SELECT * FROM sla_policies WHERE id = :id', ['id' => $id]);
        if (!$policy) { $this->notFound(); return; }
        $targets = Database::all('SELECT t.*, p.code, p.name AS p_name FROM sla_targets t JOIN priorities p ON p.id = t.priority_id WHERE t.sla_policy_id = :id ORDER BY p.sort_order', ['id' => $id]);
        $levels = Database::all('SELECT * FROM escalation_levels WHERE sla_policy_id = :id ORDER BY level', ['id' => $id]);
        $this->render('sla/edit', [
            'pageTitle' => 'SLA Policy — ' . $policy['name'], 'policy' => $policy, 'targets' => $targets, 'levels' => $levels,
            'calendars' => Database::all('SELECT * FROM business_calendars ORDER BY name'),
            'products' => Database::all('SELECT * FROM products WHERE is_active = 1 ORDER BY name'),
            'priorities' => Database::all('SELECT * FROM priorities WHERE is_active = 1 ORDER BY sort_order'),
        ]);
    }

    public function update(string $id): void
    {
        $this->requireCsrf();
        $policy = Database::one('SELECT * FROM sla_policies WHERE id = :id', ['id' => $id]);
        if (!$policy) { $this->notFound(); return; }

        Database::update('sla_policies', [
            'name' => Request::post('name'), 'calendar_id' => Request::post('calendar_id'),
            'is_24x7' => Request::post('is_24x7') ? 1 : 0, 'is_active' => Request::post('is_active') ? 1 : 0,
        ], 'id = :id', ['id' => $id]);
        $this->saveTargets((int)$id);

        Session::flash('success', 'SLA policy saved. Existing open tickets keep the targets in force at their creation (BRD 13.3).');
        $this->redirect('/admin/sla/' . $id);
    }

    private function saveTargets(int $policyId): void
    {
        $priorities = Database::all('SELECT id FROM priorities WHERE is_active = 1');
        foreach ($priorities as $p) {
            $pid = $p['id'];
            $first = Request::post("first_response_{$pid}");
            $res = Request::post("resolution_{$pid}");
            if ($first === null || $res === null || $first === '' || $res === '') continue;

            $existing = Database::one('SELECT id FROM sla_targets WHERE sla_policy_id = :pol AND priority_id = :pri', ['pol' => $policyId, 'pri' => $pid]);
            $data = [
                'first_response_minutes' => (int)$first, 'resolution_minutes' => (int)$res,
                'update_frequency_minutes' => Request::post("update_freq_{$pid}") ?: null,
                'warn_pct_1' => Request::post("warn1_{$pid}", 50), 'warn_pct_2' => Request::post("warn2_{$pid}", 80),
            ];
            if ($existing) {
                Database::update('sla_targets', $data, 'id = :id', ['id' => $existing['id']]);
            } else {
                Database::insert('sla_targets', array_merge($data, ['sla_policy_id' => $policyId, 'priority_id' => $pid]));
            }
        }
    }

    public function storeEscalationLevel(string $id): void
    {
        $this->requireCsrf();
        Database::insert('escalation_levels', [
            'sla_policy_id' => $id, 'level' => (int)Request::post('level'),
            'trigger_pct' => Request::post('trigger_pct') ?: null,
            'trigger_on_breach' => Request::post('trigger_on_breach') ? 1 : 0,
            'notify_role' => Request::post('notify_role'), 'action_note' => Request::post('action_note'),
        ]);
        Session::flash('success', 'Escalation level added.');
        $this->redirect('/admin/sla/' . $id);
    }

    public function simulate(string $id): void
    {
        $policy = Database::one('SELECT * FROM sla_policies WHERE id = :id', ['id' => $id]);
        $calendar = Database::one('SELECT * FROM business_calendars WHERE id = :id', ['id' => $policy['calendar_id']]);
        $priorityId = (int)Request::post('priority_id');
        $target = Database::one('SELECT * FROM sla_targets WHERE sla_policy_id = :p AND priority_id = :pr', ['p' => $id, 'pr' => $priorityId]);
        $from = new DateTime(Request::post('from_datetime', 'now'));

        if (!$target) { $this->json(['error' => 'No target configured for that priority.'], 422); return; }

        $responseDue = SlaEngine::addBusinessMinutes($from, (int)$target['first_response_minutes'], $calendar, (bool)$policy['is_24x7']);
        $resolutionDue = SlaEngine::addBusinessMinutes($from, (int)$target['resolution_minutes'], $calendar, (bool)$policy['is_24x7']);

        $this->json([
            'response_due' => $responseDue->format('D d M Y, H:i'),
            'resolution_due' => $resolutionDue->format('D d M Y, H:i'),
        ]);
    }
}
