<?php
declare(strict_types=1);

namespace App\Modules\Support\Services;

use App\Core\App;

final class AttachmentService
{
    private const ALLOWED_MIMES = [
        'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/bmp',
        'application/pdf',
        'text/plain', 'text/csv',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/zip', 'application/x-rar-compressed',
        'video/mp4', 'video/quicktime',
    ];

    private const MAX_FILE_SIZE = 20 * 1024 * 1024; // 20MB per file

    public static function uploadDir(): string
    {
        $dir = App::getInstance()->basePath() . '/storage/uploads/support/';
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
        return $dir;
    }

    public static function handleUploads(array $files, int $ticketId, ?int $replyId = null): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();
        $uploadDir = self::uploadDir();
        $saved = [];

        $fileList = self::normalizeFiles($files);

        foreach ($fileList as $file) {
            if ($file['error'] !== UPLOAD_ERR_OK || $file['size'] <= 0) continue;
            if ($file['size'] > self::MAX_FILE_SIZE) continue;

            $finfo = new \finfo(FILEINFO_MIME_TYPE);
            $mimeType = $finfo->file($file['tmp_name']);
            if (!in_array($mimeType, self::ALLOWED_MIMES, true)) continue;

            $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
            $storedFilename = 'tkt_' . $ticketId . '_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
            $filePath = $uploadDir . $storedFilename;

            if (!move_uploaded_file($file['tmp_name'], $filePath)) continue;

            $id = $db->insert('support_ticket_attachments', [
                'ticket_id'         => $ticketId,
                'reply_id'          => $replyId,
                'original_filename' => $file['name'],
                'stored_filename'   => $storedFilename,
                'file_path'         => 'storage/uploads/support/' . $storedFilename,
                'file_size'         => (int) $file['size'],
                'mime_type'         => $mimeType,
                'uploaded_by'       => $employee ? (int) $employee->id : null,
                'created_at'        => date('Y-m-d H:i:s'),
            ]);

            $saved[] = ['id' => $id, 'filename' => $file['name']];
        }

        return $saved;
    }

    public static function getAttachment(int $id): ?array
    {
        $db = App::getInstance()->db();
        return $db->selectOne("SELECT * FROM support_ticket_attachments WHERE id = ?", [$id]);
    }

    public static function getAbsolutePath(array $attachment): string
    {
        return App::getInstance()->basePath() . '/' . $attachment['file_path'];
    }

    private static function normalizeFiles(array $files): array
    {
        if (isset($files['name']) && is_array($files['name'])) {
            $normalized = [];
            foreach ($files['name'] as $i => $name) {
                $normalized[] = [
                    'name'     => $name,
                    'type'     => $files['type'][$i] ?? '',
                    'tmp_name' => $files['tmp_name'][$i] ?? '',
                    'error'    => $files['error'][$i] ?? UPLOAD_ERR_NO_FILE,
                    'size'     => $files['size'][$i] ?? 0,
                ];
            }
            return $normalized;
        }
        if (isset($files['name'])) {
            return [$files];
        }
        return $files;
    }

    public static function formatSize(int $bytes): string
    {
        if ($bytes >= 1048576) return round($bytes / 1048576, 1) . ' MB';
        if ($bytes >= 1024) return round($bytes / 1024, 1) . ' KB';
        return $bytes . ' B';
    }

    public static function isImage(string $mimeType): bool
    {
        return str_starts_with($mimeType, 'image/');
    }
}
