<?php
if (! defined('ABSPATH')) exit;
class UAMT_Mime_Types_Handler
{
    /**
     * Summary of instance
     * @return self
     */
    public static function instance()
    {
        static $instance = null;
        if (null === $instance) {
            $instance = new self();
        }
        return $instance;
    }
    /**
     * Summary of __construct
     */
    public function __construct()
    {
        add_filter('upload_mimes', array($this, 'uamt_allow_custom_mime_types'));

        add_action('wp_ajax_uamt_upload_mime', array($this, 'uamt_handle_file_upload'));

        add_action('wp_ajax_uamt_delete_mime', array($this, 'uamt_handle_delete_mime'));

        add_action('wp_ajax_uamt_save_settings', array($this, 'uamt_ajax_save_settings'));

        add_action('wp_ajax_uamt_reset_settings', array($this, 'uamt_reset_settings_callback'));
    }

    /**
     * Summary of uamt_get_default_mime_types
     * @return array{desc: string, ext: string, mime: string[]}
     */
    public static function uamt_get_default_mime_types()
    {
        return [
            ['desc' => 'SVG Image', 'mime' => 'image/svg+xml', 'ext' => 'svg'],
            ['desc' => 'Android Package', 'mime' => 'application/vnd.android.package-archive', 'ext' => 'apk'],
            ['desc' => 'Dts File', 'mime' => 'application/octet-stream', 'ext' => 'dts'],
            ['desc' => 'TTF File', 'mime' => 'font/sfnt', 'ext' => 'ttf'],
            ['desc' => 'OTF File', 'mime' => 'application/vnd.ms-opentype', 'ext' => 'otf'],
            ['desc' => 'WOFF File', 'mime' => 'text/html', 'ext' => 'woff'],
            ['desc' => 'Figma File', 'mime' => 'application/octet-stream', 'ext' => 'fig'],
            ['desc' => 'EOT File', 'mime' => 'text/html', 'ext' => 'eot'],
            ['desc' => 'EPUB File', 'mime' => 'application/epub+zip', 'ext' => 'epub'],
            ['desc' => 'WOFF2 File', 'mime' => 'text/html', 'ext' => 'woff2'],
            ['desc' => 'GPX File', 'mime' => 'text/xml', 'ext' => 'gpx'],
            ['desc' => 'ICO File', 'mime' => 'image/vnd.microsoft.icon', 'ext' => 'ico'],
            ['desc' => 'MSI File', 'mime' => 'application/x-msi', 'ext' => 'msi'],
            ['desc' => 'XZ File', 'mime' => 'application/x-xz', 'ext' => 'xz'],
            ['desc' => 'MKA Video File', 'mime' => 'video/x-matroska', 'ext' => 'mka'],
            ['desc' => 'Tar Z File', 'mime' => 'application/x-compress', 'ext' => 'z'],
            ['desc' => 'JSON File', 'mime' => 'application/json', 'ext' => 'json'],
            ['desc' => 'EPS File', 'mime' => 'application/postscript', 'ext' => 'eps'],
            ['desc' => 'XML File', 'mime' => 'text/html', 'ext' => 'xml'],
            ['desc' => 'Cabinet File', 'mime' => 'application/vnd.ms-cab-compressed', 'ext' => 'cab'],
            ['desc' => 'PSD File', 'mime' => 'image/vnd.adobe.photoshop', 'ext' => 'psd'],
            ['desc' => 'Amazon Kindle eBook', 'mime' => 'application/octet-stream', 'ext' => 'azw3'],
            ['desc' => 'Video m4v', 'mime' => 'video/x-m4v', 'ext' => 'm4v'],
            ['desc' => 'VCF File', 'mime' => 'text/plain', 'ext' => 'vcf'],
            ['desc' => 'Word Macro-Enabled Document', 'mime' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'ext' => 'docm'],
            ['desc' => 'Word Template', 'mime' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'ext' => 'dotx'],
            ['desc' => 'Excel Binary Workbook', 'mime' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'ext' => 'xlsb'],
            ['desc' => 'Excel Macro-Enabled Workbook', 'mime' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'ext' => 'xlsm'],
            ['desc' => 'Excel Template', 'mime' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'ext' => 'xltx'],
            ['desc' => 'PowerPoint Template', 'mime' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'ext' => 'potx'],
            ['desc' => 'PowerPoint Add-in', 'mime' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'ext' => 'ppam'],
            ['desc' => 'RAR Archive', 'mime' => 'application/x-rar', 'ext' => 'rar'],
            ['desc' => 'CSS Stylesheet', 'mime' => 'text/plain', 'ext' => 'css'],
            ['desc' => 'JavaScript', 'mime' => 'text/plain', 'ext' => 'js'],
            ['desc' => 'Executable', 'mime' => 'application/x-dosexec', 'ext' => 'exe'],
            ['desc' => 'Java Class', 'mime' => 'text/x-c', 'ext' => 'class'],
            ['desc' => 'Access Database', 'mime' => 'application/x-msaccess', 'ext' => 'mdb'],
            ['desc' => 'Project Plan', 'mime' => 'application/vnd.ms-office', 'ext' => 'mpp'],
            ['desc' => 'QuickTime Video', 'mime' => 'video/quicktime', 'ext' => 'qt'],
            ['desc' => 'MPEG Video', 'mime' => 'video/mpeg', 'ext' => 'mpe'],
            ['desc' => 'Tab-Separated Values', 'mime' => 'text/plain', 'ext' => 'tsv'],
            ['desc' => 'Flash Movie', 'mime' => 'application/x-shockwave-flash', 'ext' => 'swf'],
        ];
    }
    /**
     * Allow custom MIME types in uploads
     */
    public function uamt_allow_custom_mime_types($mimes)
    {
        $default_mimes = self::uamt_get_default_mime_types();
        $custom_mimes = get_option('uamt_custom_mimes', []);
        $allowed_extensions = get_option('uamt_allowed_mimes', []);

        // Process default MIME types
        foreach ($default_mimes as $type) {
            if (in_array($type['ext'], $allowed_extensions)) {
                $mimes[$type['ext']] = $type['mime'];
            }
        }

        // Process custom MIME types
        foreach ($custom_mimes as $type) {
            if (in_array($type['ext'], $allowed_extensions)) {
                $mimes[$type['ext']] = $type['mime'];
            }
        }

        return $mimes;
    }

    /**
     * Handle AJAX MIME type detection
     */
    public function uamt_handle_file_upload()
    {
        check_ajax_referer('uamt', 'security');

        if (!current_user_can('upload_files')) {
            wp_send_json_error(__('You do not have permission to upload files.', 'upload-any-mime-types'));
        }

        if (empty($_FILES['file'])) {
            wp_send_json_error(__('No file was uploaded.', 'upload-any-mime-types'));
        }

        $file = $_FILES['file'];

        // Check for upload errors
        if ($file['error'] !== UPLOAD_ERR_OK) {
            wp_send_json_error(sprintf(__('File upload error: %s', 'upload-any-mime-types'), $file['error']));
        }

        // Get MIME type and extension
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $file_name = sanitize_key($file['name']);
        $mime = finfo_file($finfo, $file['tmp_name']);
        finfo_close($finfo);
        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);

        // Check if extension exists in default MIME types
        $default_mimes = self::uamt_get_default_mime_types();
        $default_extensions = array_column($default_mimes, 'ext');

        // Check if extension exists in custom MIME types
        $custom_mimes = get_option('uamt_custom_mimes', array());
        $custom_extensions = array_column($custom_mimes, 'ext');

        // Combine all extensions to check
        $all_extensions = array_merge($default_extensions, $custom_extensions);

        if (in_array($ext, $all_extensions)) {
            wp_send_json_error(sprintf(__('The extension %s already exists in MIME types.', 'upload-any-mime-types'), $ext));
        }

        // Prepare new custom mime
        $new_custom_mime = array(
            'desc' => $file_name,
            'mime' => $mime,
            'ext'  => $ext
        );

        // Add new mime
        $custom_mimes[] = $new_custom_mime;
        update_option('uamt_custom_mimes', $custom_mimes);

        wp_send_json_success([
            'mime'  => $mime,
            'ext'   => $ext,
            'name'  => sanitize_file_name($file['name'])
        ]);
    }

    /**
     * Handle MIME type deletion
     */
    public function uamt_handle_delete_mime()
    {
        check_ajax_referer('uamt', 'security');

        if (!isset($_POST['extension'])) {
            wp_send_json_error('No extension provided');
        }

        $extension = sanitize_key($_POST['extension']);
        $custom_mimes = get_option('uamt_custom_mimes', []);
        $allowed_mimes = get_option('uamt_allowed_mimes', []);

        // Remove from custom MIME types
        $custom_mimes = array_filter($custom_mimes, function ($mime) use ($extension) {
            return $mime['ext'] !== $extension;
        });

        // Remove from allowed extensions
        $allowed_mimes = array_filter($allowed_mimes, function ($ext) use ($extension) {
            return $ext !== $extension;
        });

        update_option('uamt_custom_mimes', array_values($custom_mimes));
        update_option('uamt_allowed_mimes', array_values($allowed_mimes));

        wp_send_json_success('MIME type deleted successfully');
    }

    /**
     * Handle AJAX settings save
     */
    public function uamt_ajax_save_settings()
    {
        // Check if this is an AJAX request
        if (!wp_doing_ajax()) {
            wp_send_json_error(__('Invalid request', 'upload-any-mime-types'), 400);
        }

        // Verify nonce first
        if (!check_ajax_referer('uamt_settings_nonce', 'security', false)) {
            wp_send_json_error(__('Security check failed', 'upload-any-mime-types'), 403);
        }

        // Check permissions
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('You do not have permission to manage settings', 'upload-any-mime-types'), 403);
        }

        // Initialize response array
        $response = array(
            'success' => false,
            'data' => array()
        );

        try {
            // Save allowed mimes
            $allowed_mimes = array();
            if (isset($_POST['uamt_mimes']) && is_array($_POST['uamt_mimes'])) {
                $allowed_mimes = array_map('sanitize_text_field', $_POST['uamt_mimes']);
                update_option('uamt_allowed_mimes', $allowed_mimes);
                $response['data']['allowed_mimes'] = $allowed_mimes;
            }

            // Save custom mimes if provided
            if (isset($_POST['custom_mimes']) && is_array($_POST['custom_mimes'])) {
                $custom_mimes_data = $_POST['custom_mimes'];

                // Validate structure
                if (!isset($custom_mimes_data['desc']) || !isset($custom_mimes_data['mime']) || !isset($custom_mimes_data['ext'])) {
                    throw new Exception(__('Invalid MIME data structure', 'upload-any-mime-types'));
                }

                // Sanitize data
                $sanitized_data = array(
                    'desc' => array_map('sanitize_text_field', $custom_mimes_data['desc']),
                    'mime' => array_map('sanitize_text_field', $custom_mimes_data['mime']),
                    'ext' => array_map('sanitize_key', $custom_mimes_data['ext'])
                );

                // Prepare new custom mimes
                $new_custom_mimes = array();
                $existing_custom_mimes = get_option('uamt_custom_mimes', array());
                $existing_extensions = array_map(function ($type) {
                    return $type['ext'];
                }, self::uamt_get_default_mime_types());

                foreach ($sanitized_data['desc'] as $index => $desc) {
                    if (!empty($sanitized_data['desc'][$index])) {
                        $ext = $sanitized_data['ext'][$index];

                        // Check for duplicate extensions
                        if (in_array($ext, $existing_extensions)) {
                            continue; // Skip default extensions
                        }

                        $new_custom_mimes[] = array(
                            'desc' => $sanitized_data['desc'][$index],
                            'mime' => $sanitized_data['mime'][$index],
                            'ext' => $ext
                        );
                    }
                }

                // Merge with existing custom mimes (prevent duplicates)
                $merged_custom_mimes = $existing_custom_mimes;
                foreach ($new_custom_mimes as $new_mime) {
                    $exists = false;
                    foreach ($merged_custom_mimes as $existing_mime) {
                        if ($existing_mime['ext'] === $new_mime['ext']) {
                            $exists = true;
                            break;
                        }
                    }
                    if (!$exists) {
                        $merged_custom_mimes[] = $new_mime;
                    }
                }

                update_option('uamt_custom_mimes', $merged_custom_mimes);
                $response['data']['custom_mimes'] = $merged_custom_mimes;
            }

            $response['success'] = true;
            $response['message'] = __('Settings saved successfully', 'upload-any-mime-types');
        } catch (Exception $e) {
            $response['message'] = $e->getMessage();
            wp_send_json_error($response, 500);
        }

        wp_send_json_success($response);
    }

    public function uamt_reset_settings_callback()
    {
        if (!check_ajax_referer('uamt', 'security', false)) {
            wp_send_json_error(array('message' => 'Invalid security token.'));
            wp_die();
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'Permission denied.'));
            wp_die();
        }

        delete_option('uamt_mimes');
        delete_option('uamt_custom_mimes');
        delete_option('uamt_allowed_mimes');

        wp_send_json_success(array(
            'message' => __('Settings reset successfully.', 'upload-any-mime-types')
        ));
    }
}

UAMT_Mime_Types_Handler::instance();
