<?php
declare(strict_types=1);

namespace App\Modules\Support\Models;

use App\Core\App;
use App\Core\Pagination;

class Ticket
{
    public static function find(int $id): ?array
    {
        $db = App::getInstance()->db();
        return $db->selectOne(
            "SELECT t.*, e.full_name_ar as created_by_name, ae.full_name_ar as assigned_to_name
             FROM support_tickets t
             LEFT JOIN employees e ON e.id = t.created_by_employee_id
             LEFT JOIN employees ae ON ae.id = t.assigned_to_employee_id
             WHERE t.id = ?",
            [$id]
        );
    }

    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $db = App::getInstance()->db();
        $where = '1=1';
        $params = [];

        if (!empty($filters['status'])) {
            $where .= ' AND t.status = ?';
            $params[] = $filters['status'];
        }
        if (!empty($filters['priority'])) {
            $where .= ' AND t.priority = ?';
            $params[] = $filters['priority'];
        }
        if (!empty($filters['category'])) {
            $where .= ' AND t.category = ?';
            $params[] = $filters['category'];
        }
        if (!empty($filters['assigned_to'])) {
            $where .= ' AND t.assigned_to_employee_id = ?';
            $params[] = (int) $filters['assigned_to'];
        }
        if (!empty($filters['search'])) {
            $where .= ' AND (t.ticket_number LIKE ? OR t.subject LIKE ? OR t.body LIKE ?)';
            $s = '%' . $filters['search'] . '%';
            $params[] = $s; $params[] = $s; $params[] = $s;
        }

        $countRow = $db->selectOne("SELECT COUNT(*) as cnt FROM support_tickets t WHERE {$where}", $params);
        $total = (int) ($countRow['cnt'] ?? 0);
        $offset = ($page - 1) * $perPage;

        $rows = $db->select(
            "SELECT t.*, e.full_name_ar as created_by_name, ae.full_name_ar as assigned_to_name
             FROM support_tickets t
             LEFT JOIN employees e ON e.id = t.created_by_employee_id
             LEFT JOIN employees ae ON ae.id = t.assigned_to_employee_id
             WHERE {$where}
             ORDER BY FIELD(t.status, 'open', 'in_progress', 'waiting', 'closed'),
                      FIELD(t.priority, 'urgent', 'high', 'normal', 'low'),
                      t.updated_at DESC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        return ['data' => $rows, 'pagination' => Pagination::paginate($total, $perPage, $page)];
    }

    public static function getReplies(int $ticketId): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT r.*, e.full_name_ar as employee_name
             FROM support_ticket_replies r
             LEFT JOIN employees e ON e.id = r.employee_id
             WHERE r.ticket_id = ?
             ORDER BY r.created_at ASC",
            [$ticketId]
        );
    }

    public static function getAttachments(int $ticketId, ?int $replyId = null): array
    {
        $db = App::getInstance()->db();
        if ($replyId !== null) {
            return $db->select(
                "SELECT * FROM support_ticket_attachments WHERE reply_id = ? ORDER BY id ASC",
                [$replyId]
            );
        }
        return $db->select(
            "SELECT * FROM support_ticket_attachments WHERE ticket_id = ? ORDER BY id ASC",
            [$ticketId]
        );
    }

    public static function getAllAttachments(int $ticketId): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT a.*, e.full_name_ar as uploaded_by_name
             FROM support_ticket_attachments a
             LEFT JOIN employees e ON e.id = a.uploaded_by
             WHERE a.ticket_id = ?
             ORDER BY a.created_at ASC",
            [$ticketId]
        );
    }

    public static function generateNumber(): string
    {
        $db = App::getInstance()->db();
        $year = date('Y');
        $row = $db->selectOne(
            "SELECT MAX(CAST(SUBSTRING(ticket_number, 10) AS UNSIGNED)) as max_num
             FROM support_tickets WHERE ticket_number LIKE ?",
            ["TKT-{$year}-%"]
        );
        $next = ((int) ($row['max_num'] ?? 0)) + 1;
        return sprintf('TKT-%s-%06d', $year, $next);
    }

    public static function getStatusLabel(string $status): string
    {
        return match ($status) {
            'open'        => 'مفتوحة',
            'in_progress' => 'قيد المعالجة',
            'waiting'     => 'في الانتظار',
            'closed'      => 'مغلقة',
            default       => $status,
        };
    }

    public static function getPriorityLabel(string $priority): string
    {
        return match ($priority) {
            'urgent' => 'عاجل',
            'high'   => 'مرتفع',
            'normal' => 'عادي',
            'low'    => 'منخفض',
            default  => $priority,
        };
    }

    public static function getCategoryLabel(string $category): string
    {
        return match ($category) {
            'bug'         => 'خلل فني',
            'feature'     => 'طلب ميزة',
            'question'    => 'استفسار',
            'data_fix'    => 'تصحيح بيانات',
            'permissions' => 'صلاحيات',
            'printing'    => 'طباعة',
            'financial'   => 'مالي',
            'other'       => 'أخرى',
            default       => $category ?? 'أخرى',
        };
    }

    public static function getCategories(): array
    {
        return [
            'bug'         => 'خلل فني',
            'feature'     => 'طلب ميزة',
            'question'    => 'استفسار',
            'data_fix'    => 'تصحيح بيانات',
            'permissions' => 'صلاحيات',
            'printing'    => 'طباعة',
            'financial'   => 'مالي',
            'other'       => 'أخرى',
        ];
    }

    public static function countByStatus(): array
    {
        $db = App::getInstance()->db();
        $rows = $db->select("SELECT status, COUNT(*) as cnt FROM support_tickets GROUP BY status");
        $result = ['open' => 0, 'in_progress' => 0, 'waiting' => 0, 'closed' => 0];
        foreach ($rows as $row) {
            $result[$row['status']] = (int) $row['cnt'];
        }
        return $result;
    }
}
