<?php
declare(strict_types=1);

namespace App\Modules\Support\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Support\Models\Ticket;
use App\Modules\Support\Services\AttachmentService;

class TicketController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('support.view');

        $filters = [
            'status'      => trim((string) $request->get('status', '')),
            'priority'    => trim((string) $request->get('priority', '')),
            'category'    => trim((string) $request->get('category', '')),
            'assigned_to' => trim((string) $request->get('assigned_to', '')),
            'search'      => trim((string) $request->get('search', '')),
        ];
        $page = max(1, (int) $request->get('page', 1));
        $result = Ticket::search($filters, 20, $page);
        $counts = Ticket::countByStatus();

        return $this->view('Support.Views.index', [
            'tickets'    => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
            'counts'     => $counts,
        ]);
    }

    public function create(Request $request): Response
    {
        $this->authorize('support.create');
        $db = App::getInstance()->db();
        $employees = $db->select("SELECT id, full_name_ar FROM employees WHERE is_active = 1 ORDER BY full_name_ar");

        return $this->view('Support.Views.create', [
            'categories' => Ticket::getCategories(),
            'employees'  => $employees,
        ]);
    }

    public function store(Request $request): Response
    {
        $this->authorize('support.create');
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $subject  = trim((string) $request->post('subject', ''));
        $body     = trim((string) $request->post('body', ''));
        $priority = trim((string) $request->post('priority', 'normal'));
        $category = trim((string) $request->post('category', ''));
        $assignTo = (int) $request->post('assigned_to', 0);

        if ($subject === '' || $body === '') {
            return $this->redirect('/support/create')->withError('الموضوع والمحتوى مطلوبان');
        }

        $ticketNumber = Ticket::generateNumber();
        $branch = App::getInstance()->currentBranch();

        $ticketId = $db->insert('support_tickets', [
            'ticket_number'          => $ticketNumber,
            'subject'                => $subject,
            'body'                   => $body,
            'priority'               => in_array($priority, ['urgent', 'high', 'normal', 'low']) ? $priority : 'normal',
            'status'                 => 'open',
            'category'               => $category ?: null,
            'created_by_employee_id' => $employee ? (int) $employee->id : null,
            'assigned_to_employee_id'=> $assignTo > 0 ? $assignTo : null,
            'branch_id'              => $branch ? (int) $branch['id'] : null,
            'created_at'             => date('Y-m-d H:i:s'),
            'updated_at'             => date('Y-m-d H:i:s'),
        ]);

        if (!empty($_FILES['attachments'])) {
            AttachmentService::handleUploads($_FILES['attachments'], (int) $ticketId);
        }

        return $this->redirect('/support/' . $ticketId)->withSuccess('تم إنشاء التذكرة — رقم: ' . $ticketNumber);
    }

    public function show(Request $request, string $id): Response
    {
        $this->authorize('support.view');
        $ticket = Ticket::find((int) $id);
        if (!$ticket) return $this->redirect('/support')->withError('التذكرة غير موجودة');

        $replies = Ticket::getReplies((int) $id);
        $attachments = Ticket::getAllAttachments((int) $id);
        $replyAttachments = [];
        foreach ($attachments as $a) {
            if ($a['reply_id']) {
                $replyAttachments[(int) $a['reply_id']][] = $a;
            }
        }
        $ticketAttachments = array_filter($attachments, fn($a) => empty($a['reply_id']));

        $db = App::getInstance()->db();
        $employees = $db->select("SELECT id, full_name_ar FROM employees WHERE is_active = 1 ORDER BY full_name_ar");

        return $this->view('Support.Views.show', [
            'ticket'            => $ticket,
            'replies'           => $replies,
            'ticketAttachments' => $ticketAttachments,
            'replyAttachments'  => $replyAttachments,
            'employees'         => $employees,
        ]);
    }

    public function reply(Request $request, string $id): Response
    {
        $this->authorize('support.reply');
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $ticket = Ticket::find((int) $id);
        if (!$ticket) return $this->redirect('/support')->withError('التذكرة غير موجودة');

        $body = trim((string) $request->post('body', ''));
        if ($body === '') return $this->redirect('/support/' . $id)->withError('محتوى الرد مطلوب');

        $replyId = $db->insert('support_ticket_replies', [
            'ticket_id'   => (int) $id,
            'body'        => $body,
            'employee_id' => $employee ? (int) $employee->id : null,
            'created_at'  => date('Y-m-d H:i:s'),
        ]);

        if (!empty($_FILES['attachments'])) {
            AttachmentService::handleUploads($_FILES['attachments'], (int) $id, (int) $replyId);
        }

        $newStatus = $ticket['status'] === 'open' ? 'in_progress' : $ticket['status'];
        $db->update('support_tickets', [
            'status'     => $newStatus,
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/support/' . $id)->withSuccess('تم إضافة الرد');
    }

    public function close(Request $request, string $id): Response
    {
        $this->authorize('support.close');
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $ticket = Ticket::find((int) $id);
        if (!$ticket) return $this->redirect('/support')->withError('التذكرة غير موجودة');

        $db->update('support_tickets', [
            'status'     => 'closed',
            'closed_at'  => date('Y-m-d H:i:s'),
            'closed_by'  => $employee ? (int) $employee->id : null,
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/support/' . $id)->withSuccess('تم إغلاق التذكرة');
    }

    public function reopen(Request $request, string $id): Response
    {
        $this->authorize('support.manage');
        $db = App::getInstance()->db();

        $ticket = Ticket::find((int) $id);
        if (!$ticket) return $this->redirect('/support')->withError('التذكرة غير موجودة');

        $db->update('support_tickets', [
            'status'     => 'open',
            'closed_at'  => null,
            'closed_by'  => null,
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/support/' . $id)->withSuccess('تم إعادة فتح التذكرة');
    }

    public function assign(Request $request, string $id): Response
    {
        $this->authorize('support.assign');
        $db = App::getInstance()->db();

        $ticket = Ticket::find((int) $id);
        if (!$ticket) return $this->redirect('/support')->withError('التذكرة غير موجودة');

        $assignTo = (int) $request->post('assigned_to', 0);

        $db->update('support_tickets', [
            'assigned_to_employee_id' => $assignTo > 0 ? $assignTo : null,
            'status'                  => $ticket['status'] === 'open' ? 'in_progress' : $ticket['status'],
            'updated_at'              => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/support/' . $id)->withSuccess('تم تعيين التذكرة');
    }

    public function download(Request $request, string $id): Response
    {
        $this->authorize('support.view');

        $attachment = AttachmentService::getAttachment((int) $id);
        if (!$attachment) return $this->redirect('/support')->withError('المرفق غير موجود');

        $absPath = AttachmentService::getAbsolutePath($attachment);
        if (!file_exists($absPath)) return $this->redirect('/support')->withError('الملف غير موجود على السيرفر');

        header('Content-Type: ' . $attachment['mime_type']);
        header('Content-Disposition: inline; filename="' . $attachment['original_filename'] . '"');
        header('Content-Length: ' . filesize($absPath));
        readfile($absPath);
        exit;
    }
}
