<?php
/**
 * 🎨 APPEARANCE SETTINGS CONTROLLER - V2.2 PURE
 *
 * Manages dashboard appearance customization:
 * - Logo and branding
 * - Color schemes
 * - UI preferences
 *
 * @package FleekDash\Controllers
 * @since 2.2.0
 */

namespace FleekDash\Controllers;

use WP_REST_Request;
use FleekDash\Services\ResponseService;

/**
 * Class AppearanceSettingsController
 *
 * Pure V2.2 Controller - No legacy dependencies
 *
 * @package FleekDash\Controllers
 */
class AppearanceSettingsController
{
    /** MIME type for PNG images - used in logo upload */
    private const MIME_PNG = 'image/png';

    /**
     * 🎯 Get appearance settings
     *
     * @param WP_REST_Request $_request REST callback signature - unused for GET
     * @return \WP_REST_Response
     */
    public function getAppearanceSettings(WP_REST_Request $_request) // NOSONAR php:S1172 - WP REST callback
    {
        try {
            $settings = [
                'logo' => \get_option('_fleekdash_logo', ''),
                'dark_logo' => \get_option('_fleekdash_dark_logo', ''),
                'use_dark_logo' => \get_option('_fleekdash_use_dark_logo', false),
                'auto_invert_logo_dark_mode' => \get_option('_fleekdash_auto_invert_logo_dark_mode', true),
                'favicon' => \get_option('_fleekdash_favicon', ''),
                'brand_name' => \get_option('_fleekdash_brand_name', \get_bloginfo('name')),
                'primary_color' => \get_option('_fleekdash_primary_color', '#3858e9'),
                'secondary_color' => \get_option('_fleekdash_secondary_color', '#64748b'),
                'accent_color' => \get_option('_fleekdash_accent_color', '#f59e0b'),
                'sidebar_width' => \get_option('_fleekdash_sidebar_width', '280'),
                'enable_animations' => \get_option('_fleekdash_enable_animations', true),
                'enable_shadows' => \get_option('_fleekdash_enable_shadows', true),
                'enable_rounded_corners' => \get_option('_fleekdash_enable_rounded_corners', true),
            ];

            return ResponseService::success('Appearance settings retrieved', $settings);

        } catch (\Exception $e) {
            return ResponseService::error(
                'Failed to retrieve appearance settings',
                ['error' => $e->getMessage()],
                500
            );
        }
    }

    /**
     * 🔧 Update appearance settings
     *
     * @param WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function updateAppearanceSettings(WP_REST_Request $request) // NOSONAR php:S1142 - multiple returns for REST error handling
    {
        $result = null;
        try {
            $params = $request->get_json_params();
            if (!$params) {
                $result = ResponseService::error('Invalid parameters', null, 400);
            } else {
                $validationError = $this->validateAndApplyUpdates($params);
                if ($validationError !== null) {
                    $result = $validationError;
                } else {
                    \do_action('fleekdash_appearance_settings_updated', $params);
                    $result = ResponseService::success('Appearance settings updated successfully');
                }
            }
        } catch (\Exception $e) {
            $result = ResponseService::error(
                'Failed to update appearance settings',
                ['error' => $e->getMessage()],
                500
            );
        }
        return $result;
    }

    /**
     * Validate and apply field updates. Returns error response or null on success.
     *
     * @param array $params
     * @return \WP_REST_Response|null
     */
    private function validateAndApplyUpdates(array $params): ?\WP_REST_Response // NOSONAR php:S1142 - early returns for validation clarity
    {
        $allowed_fields = [
            'logo', 'dark_logo', 'use_dark_logo', 'auto_invert_logo_dark_mode', 'favicon',
            'primary_color', 'secondary_color', 'accent_color', 'sidebar_width',
            'enable_animations', 'enable_shadows', 'enable_rounded_corners', 'brand_name'
        ];

        $updated = false;
        $error = null;

        foreach ($allowed_fields as $field) {
            if (!isset($params[$field])) {
                continue;
            }

            $value = $params[$field];

            $error = $this->validateColorField($field, $value);
            if ($error !== null) {
                break;
            }

            $sidebarResult = $this->validateSidebarWidth($field, $value);
            if ($sidebarResult['error'] !== null) {
                $error = $sidebarResult['error'];
                break;
            }
            if ($sidebarResult['value'] !== null) {
                $value = $sidebarResult['value'];
            }

            if (in_array($field, ['use_dark_logo', 'auto_invert_logo_dark_mode', 'enable_animations', 'enable_shadows', 'enable_rounded_corners'], true)) {
                $value = (bool) $value;
            }

            \update_option('_fleekdash_' . $field, $value);
            $updated = true;
        }

        if ($error !== null) {
            return $error;
        }
        if (!$updated) {
            return ResponseService::error('No valid fields to update', null, 400);
        }
        return null;
    }

    private function validateColorField(string $field, mixed $value): ?\WP_REST_Response
    {
        if (!in_array($field, ['primary_color', 'secondary_color', 'accent_color'], true)) {
            return null;
        }
        if (!is_string($value) || !preg_match('/^#[0-9a-fA-F]{6}$/', $value)) {
            return ResponseService::error("Invalid color format for {$field}", null, 400);
        }
        return null;
    }

    /**
     * Validate sidebar width. Returns error or validated int value.
     *
     * @return array{error: \WP_REST_Response|null, value: int|null}
     */
    private function validateSidebarWidth(string $field, mixed $value): array
    {
        if ($field !== 'sidebar_width') {
            return ['error' => null, 'value' => null];
        }
        $width = (int) $value;
        if ($width < 200 || $width > 400) {
            return [
                'error' => ResponseService::error('Sidebar width must be between 200 and 400px', null, 400),
                'value' => null,
            ];
        }
        return ['error' => null, 'value' => $width];
    }

    /**
     * 📤 Upload logo
     *
     * @param WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function uploadLogo(WP_REST_Request $request)
    {
        $fileError = $this->validateLogoUpload();
        if ($fileError !== null) {
            return $fileError;
        }

        $file = $_FILES['logo'];
        $logo_type = $request->get_param('type') ?: 'light';

        $validationError = $this->validateLogoFile($file);
        if ($validationError !== null) {
            return $validationError;
        }

        return $this->processLogoUpload($file, $logo_type);
    }

    private function validateLogoUpload(): ?\WP_REST_Response
    {
        if (!isset($_FILES['logo'])) {
            return ResponseService::error('No file uploaded', null, 400);
        }
        return null;
    }

    private function validateLogoFile(array $file): ?\WP_REST_Response
    {
        $allowed_types = ['image/jpeg', 'image/jpg', self::MIME_PNG, 'image/svg+xml', 'image/webp'];
        if (!in_array($file['type'], $allowed_types, true)) {
            return ResponseService::error('Invalid file type. Allowed: JPEG, PNG, SVG, WebP', null, 400);
        }

        $max_size = 5 * 1024 * 1024; // 5MB
        if ($file['size'] > $max_size) {
            return ResponseService::error('File too large. Maximum size: 5MB', null, 400);
        }

        return null;
    }

    private function processLogoUpload(array $file, string $logo_type): \WP_REST_Response
    {
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';

        $upload_overrides = [
            'test_form' => false,
            'mimes' => [
                'jpg|jpeg' => 'image/jpeg',
                'png' => self::MIME_PNG,
                'svg' => 'image/svg+xml',
                'webp' => 'image/webp'
            ]
        ];

        $uploaded_file = \wp_handle_upload($file, $upload_overrides);

        if (isset($uploaded_file['error'])) {
            return ResponseService::error('Upload failed: ' . $uploaded_file['error'], null, 500);
        }

        if (!isset($uploaded_file['url'])) {
            return ResponseService::error('Failed to upload logo - no URL returned', null, 500);
        }

        $option_name = $logo_type === 'dark' ? '_fleekdash_dark_logo' : '_fleekdash_logo';
        \update_option($option_name, $uploaded_file['url']);

        $attachment_id = $this->createLogoAttachment($uploaded_file, $logo_type);

        return ResponseService::success(
            ucfirst($logo_type) . ' logo uploaded successfully',
            [
                'url' => $uploaded_file['url'],
                'type' => $logo_type,
                'attachment_id' => $attachment_id
            ]
        );
    }

    private function createLogoAttachment(array $uploaded_file, string $logo_type): ?int
    {
        try {
            $mime_type = $uploaded_file['type'] ?? self::MIME_PNG;
            $attachment = [
                'guid' => $uploaded_file['url'],
                'post_mime_type' => $mime_type,
                'post_title' => 'FleekDash ' . ucfirst($logo_type) . ' Logo',
                'post_content' => '',
                'post_status' => 'inherit'
            ];

            $attachment_id = \wp_insert_attachment($attachment, $uploaded_file['file']);

            if ($attachment_id && !\is_wp_error($attachment_id)) {
                $this->generateAttachmentMetadata($attachment_id, $uploaded_file['file']);

                $attachment_option_name = $logo_type === 'dark' ? '_fleekdash_dark_logo_id' : '_fleekdash_logo_id';
                \update_option($attachment_option_name, $attachment_id);

                return (int) $attachment_id;
            }
        } catch (\Exception $e) {
            if (\function_exists('fleekdash_log_debug')) {
                \fleekdash_log_debug('Logo attachment creation skipped: ' . $e->getMessage());
            }
        }

        return null;
    }

    private function generateAttachmentMetadata(int $attachment_id, string $file_path): void
    {
        try {
            if (\function_exists('wp_generate_attachment_metadata')) {
                $metadata = \wp_generate_attachment_metadata($attachment_id, $file_path);
                if (!empty($metadata)) {
                    \wp_update_attachment_metadata($attachment_id, $metadata);
                }
            }
        } catch (\Exception $e) {
            if (\function_exists('fleekdash_log_debug')) {
                \fleekdash_log_debug('Logo metadata generation skipped: ' . $e->getMessage());
            }
        }
    }
}
