<?php

namespace MODELORA\Upload;

if (! defined('ABSPATH')) {
    exit;
}

class Manager
{
    private array $supported = ['glb', 'gltf', 'fbx', 'obj', 'stl', 'dae', 'usdz'];

    public function register(): void
    {
        add_filter('upload_mimes', [$this, 'register_mimes']);
        add_filter('wp_check_filetype_and_ext', [$this, 'check_filetype'], 10, 4);
    }

    public function check_filetype(array $data, string $file, string $filename, $mimes = null): array
    {
        $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
        
        if (in_array($ext, $this->supported, true)) {
            $updated_mimes = $this->register_mimes(is_array($mimes) ? $mimes : []);
            if (isset($updated_mimes[$ext])) {
                $data['ext'] = $ext;
                $data['type'] = $updated_mimes[$ext];
                $data['proper_filename'] = $filename;
            }
        }
        
        return $data;
    }

    public function register_mimes(array $mimes): array
    {
        $mimes['glb'] = 'model/gltf-binary';
        $mimes['gltf'] = 'model/gltf+json';
        $mimes['obj'] = 'text/plain';
        $mimes['stl'] = 'model/stl';
        $mimes['dae'] = 'model/vnd.collada+xml';
        $mimes['fbx'] = 'application/octet-stream';
        $mimes['usdz'] = 'model/vnd.usdz+zip';

        return $mimes;
    }

    public function validate_file(array $file): array
    {
        $extension = strtolower(pathinfo($file['name'] ?? '', PATHINFO_EXTENSION));
        $size_mb = isset($file['size']) ? ((int) $file['size'] / 1024 / 1024) : 0;
        $max_upload = (int) (get_option('modelora_settings')['max_upload_mb'] ?? 50);

        if (empty($file['tmp_name']) || ! is_string($file['tmp_name']) || ! file_exists($file['tmp_name'])) {
            return [
                'success' => false,
                'error' => __('The uploaded file is missing or unreadable.', 'modelora-3d-product-viewer'),
                'issue_code' => 'UPLOAD_FILE_MISSING',
            ];
        }

        if (! is_readable($file['tmp_name']) || filesize($file['tmp_name']) === 0) {
            return [
                'success' => false,
                'error' => __('The uploaded file appears corrupted or empty.', 'modelora-3d-product-viewer'),
                'issue_code' => 'UPLOAD_FILE_CORRUPT',
            ];
        }

        if (! in_array($extension, $this->supported, true)) {
            return [
                'success' => false,
                'error' => __('Unsupported format. Please upload GLB, GLTF, FBX, OBJ, STL, DAE, or USDZ.', 'modelora-3d-product-viewer'),
                'extension' => $extension,
                'issue_code' => 'UPLOAD_EXT_UNSUPPORTED',
            ];
        }

        if ($size_mb > $max_upload) {
            return [
                'success' => false,
                'error' => __('Your file is too large. Click here to optimize.', 'modelora-3d-product-viewer'),
                'size_mb' => round($size_mb, 2),
                'issue_code' => 'UPLOAD_SIZE_LIMIT',
            ];
        }

        if ($extension === 'glb') {
            $header = @file_get_contents($file['tmp_name'], false, null, 0, 4);
            if ($header !== 'glTF') {
                return [
                    'success' => false,
                    'error' => __('This GLB file appears corrupted (invalid header).', 'modelora-3d-product-viewer'),
                    'extension' => $extension,
                    'issue_code' => 'UPLOAD_GLB_INVALID_HEADER',
                ];
            }
        }

        return [
            'success' => true,
            'extension' => $extension,
            'size_mb' => round($size_mb, 2),
            'needs_conversion' => $extension !== 'glb',
        ];
    }

    public function convert_to_glb(string $source_path, string $extension, array $options = []): array
    {
        if ($extension === 'glb') {
            return ['success' => true, 'path' => $source_path, 'optimized' => false, 'warnings' => []];
        }

        $result = apply_filters('modelora_convert_to_glb', null, $source_path, $extension, $options);
        if (is_array($result) && ! empty($result['success'])) {
            if (empty($result['warnings']) || ! is_array($result['warnings'])) {
                $result['warnings'] = [];
            }
            return $result;
        }

        return [
            'success' => false,
            'error' => __('Conversion provider is not configured. Use Convert to GLB in the dashboard (client-side converter) or register the modelora_convert_to_glb filter.', 'modelora-3d-product-viewer'),
            'issue_code' => 'CONVERTER_NOT_CONFIGURED',
        ];
    }
}

