<?php

class StoreSettingsService {
    private $pdo;
    private $storeId;

    public function __construct(PDO $pdo, int $storeId) {
        $this->pdo = $pdo;
        $this->storeId = $storeId;
        
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
    }

    /**
     * Gera um token CSRF e armazena na sessão
     */
    public function generateCsrfToken(): string {
        if (empty($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
        return $_SESSION['csrf_token'];
    }

    /**
     * Valida o token CSRF
     */
    public function validateCsrf(?string $token): bool {
        if (empty($token) || empty($_SESSION['csrf_token'])) {
            return false;
        }
        return hash_equals($_SESSION['csrf_token'], $token);
    }

    public function handleRequest(string $action, array $postData, array $files): array {
        // Validação de segurança global
        if (!$this->validateCsrf($postData['csrf_token'] ?? '')) {
            throw new Exception("Token de segurança inválido. Recarregue a página.");
        }

        switch ($action) {
            case 'update_appearance':
                return $this->updateAppearance($postData, $files);
            case 'update_social':
                return $this->updateSocial($postData);
            case 'update_seo':
                return $this->updateSeo($postData);
            case 'update_domain':
                return $this->updateDomain($postData);
            default:
                throw new Exception("Ação inválida.");
        }
    }

    private function updateAppearance(array $data, array $files): array {
        $currentSettings = $this->getTemplateSettings();
        $headerSettings = $currentSettings['header'] ?? [];

        $logoType = $data['logo_type'] ?? 'text';
        $logoText = trim($data['logo_text'] ?? '');
        
        // Handle Logo Upload
        $logoImage = $headerSettings['logo_image'] ?? '';
        
        // Check for removal
        if (isset($data['remove_logo']) && $data['remove_logo'] === '1') {
             if ($logoImage) {
                 $uploadBase = __DIR__ . '/../../uploads/';
                 $relativePath = str_replace('/uploads/', '', $logoImage);
                 $systemOldPath = $uploadBase . $relativePath;
                 if (file_exists($systemOldPath) && is_file($systemOldPath)) {
                     @unlink($systemOldPath);
                 }
             }
             $logoImage = '';
        }

        if (isset($files['logo_file']) && $files['logo_file']['error'] === UPLOAD_ERR_OK) {
            $logoImage = $this->handleFileUpload($files['logo_file'], 'logos', $headerSettings['logo_image'] ?? null);
        }

        // Handle Favicon Upload
        $favicon = $headerSettings['favicon'] ?? '';

        // Check for removal
        if (isset($data['remove_favicon']) && $data['remove_favicon'] === '1') {
             if ($favicon) {
                 $uploadBase = __DIR__ . '/../../uploads/';
                 $relativePath = str_replace('/uploads/', '', $favicon);
                 $systemOldPath = $uploadBase . $relativePath;
                 if (file_exists($systemOldPath) && is_file($systemOldPath)) {
                     @unlink($systemOldPath);
                 }
             }
             $favicon = '';
        }

        if (isset($files['favicon_file']) && $files['favicon_file']['error'] === UPLOAD_ERR_OK) {
            $favicon = $this->handleFileUpload($files['favicon_file'], 'favicons', $headerSettings['favicon'] ?? null);
        }

        // Save
        $currentSettings['header'] = array_merge($headerSettings, [
            'logo_type' => $logoType,
            'logo_text' => $logoText,
            'logo_image' => $logoImage,
            'favicon' => $favicon
        ]);

        $stmt = $this->pdo->prepare("UPDATE stores SET template_settings = ?, updated_at = NOW() WHERE id = ?");
        $stmt->execute([json_encode($currentSettings), $this->storeId]);

        return ['success' => true, 'message' => 'Aparência atualizada com sucesso!'];
    }

    private function updateDomain(array $data): array {
        $domainType = $data['domain_type'] ?? 'subdomain';
        $customDomain = trim($data['custom_domain'] ?? '');

        // Security check for premium feature
        if ($domainType === 'custom' && function_exists('shouldLockFeature') && shouldLockFeature('custom_domain')) {
            return ['success' => false, 'message' => 'Domínio próprio é um recurso Premium.'];
        }

        // Validate type
        if (!in_array($domainType, ['path', 'subdomain', 'custom'])) {
            $domainType = 'subdomain';
        }

        // Validate and Sanitize custom domain
        if ($domainType === 'custom' && !empty($customDomain)) {
            // Remove protocol and trailing slash
            $customDomain = preg_replace('#^https?://#', '', $customDomain);
            $customDomain = rtrim($customDomain, '/');
            // Remove invalid characters (Sanitization)
            $customDomain = preg_replace('/[^a-zA-Z0-9\.\-]/', '', $customDomain);
            
            // Basic structure validation
            if (!preg_match('/^(?:[-A-Za-z0-9]+\.)+[A-Za-z]{2,6}$/', $customDomain)) {
                 return ['success' => false, 'message' => 'Formato de domínio inválido.'];
            }
        }

        $stmt = $this->pdo->prepare("UPDATE stores SET domain_type = ?, custom_domain = ?, updated_at = NOW() WHERE id = ?");
        $stmt->execute([$domainType, $customDomain ?: null, $this->storeId]);

        return ['success' => true, 'message' => 'Configurações de domínio atualizadas!'];
    }

    private function updateSocial(array $data): array {
        $currentSettings = $this->getTemplateSettings();
        
        $currentSettings['social_links'] = [
            'instagram' => trim($data['instagram'] ?? ''),
            'facebook' => trim($data['facebook'] ?? ''),
            'whatsapp' => trim($data['whatsapp'] ?? ''),
            'tiktok' => trim($data['tiktok'] ?? '')
        ];

        $stmt = $this->pdo->prepare("UPDATE stores SET template_settings = ?, updated_at = NOW() WHERE id = ?");
        $stmt->execute([json_encode($currentSettings), $this->storeId]);

        return ['success' => true, 'message' => 'Redes sociais atualizadas!'];
    }

    private function updateSeo(array $data): array {
        // Handle SEO (Template Settings)
        $currentSettings = $this->getTemplateSettings();
        if (!isset($currentSettings['seo'])) {
            $currentSettings['seo'] = [];
        }
        
        // Standard SEO
        $currentSettings['seo']['meta_title'] = trim($data['meta_title'] ?? '');
        $currentSettings['seo']['meta_description'] = trim($data['meta_description'] ?? '');
        $currentSettings['seo']['keywords'] = trim($data['keywords'] ?? '');
        
        // Social SEO
        $currentSettings['seo']['social_title'] = trim($data['social_title'] ?? '');
        $currentSettings['seo']['social_description'] = trim($data['social_description'] ?? '');

        // Handle Image Upload
        if (isset($_FILES['social_image_file']) && $_FILES['social_image_file']['error'] === UPLOAD_ERR_OK) {
            try {
                $oldFile = $currentSettings['seo']['social_image'] ?? null;
                // Reuse existing handleFileUpload helper
                $url = $this->handleFileUpload($_FILES['social_image_file'], 'seo', $oldFile);
                $currentSettings['seo']['social_image'] = $url;
            } catch (Exception $e) {
                throw new Exception("Erro ao enviar imagem: " . $e->getMessage());
            }
        }

        // Handle Image Removal
        if (isset($data['remove_social_image']) && $data['remove_social_image'] === '1') {
            $oldFile = $currentSettings['seo']['social_image'] ?? null;
            if ($oldFile) {
                // Basic cleanup logic (optional, handleFileUpload does it if we passed it, but here we just clearing)
                // We'd need to manually unlink if we want to clean up disk space immediately.
                // Assuming handleFileUpload logic only deletes when REPLACING.
                // Let's rely on standard practice or add unlink here if path known.
                // For safety, just clear the link for now.
                $relativePath = str_replace('/uploads/', '', $oldFile);
                $uploadBase = __DIR__ . '/../../uploads/'; 
                $systemOldPath = $uploadBase . $relativePath;
                if (file_exists($systemOldPath) && is_file($systemOldPath)) {
                    @unlink($systemOldPath);
                }
            }
            $currentSettings['seo']['social_image'] = '';
        }

        // Save Template Settings
        $stmt = $this->pdo->prepare("UPDATE stores SET template_settings = ?, updated_at = NOW() WHERE id = ?");
        $stmt->execute([json_encode($currentSettings), $this->storeId]);

        return ['success' => true, 'message' => 'SEO e configurações sociais atualizados com sucesso!'];
    }

    private function handleFileUpload(array $file, string $subdir, ?string $oldFile = null): string {
        // 1. Verify MIME Type (Strict)
        $finfo = new finfo(FILEINFO_MIME_TYPE);
        $mimeType = $finfo->file($file['tmp_name']);
        
        $allowedMimes = [
            'image/jpeg' => 'jpg',
            'image/png' => 'png', 
            'image/webp' => 'webp',
            'image/gif' => 'gif',
            'image/x-icon' => 'ico',
            'image/vnd.microsoft.icon' => 'ico'
        ];

        if (!array_key_exists($mimeType, $allowedMimes)) {
            throw new Exception("Tipo de arquivo inválido ($mimeType). Apenas imagens são permitidas.");
        }

        // 2. Setup directory
        $extension = $allowedMimes[$mimeType];
        $uploadBase = __DIR__ . '/../../uploads/'; 
        $targetDir = $uploadBase . $subdir . '/';
        
        if (!is_dir($targetDir)) {
            mkdir($targetDir, 0755, true);
        }

        // 3. Garbage Collection (Delete old file BEFORE saving new one)
        if ($oldFile) {
            $relativePath = str_replace('/uploads/', '', $oldFile);
            $systemOldPath = $uploadBase . $relativePath;
            
            if (file_exists($systemOldPath) && is_file($systemOldPath)) {
                @unlink($systemOldPath);
            }
        }

        // 4. Generate secure name with unique hash
        $hash = bin2hex(random_bytes(8));
        $filename = "store_{$this->storeId}_{$subdir}_" . time() . "_{$hash}.{$extension}";
        $targetPath = $targetDir . $filename;

        // 5. Move file
        if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
            throw new Exception("Falha ao salvar o arquivo.");
        }

        return '/uploads/' . $subdir . '/' . $filename;
    }

    private function getTemplateSettings(): array {
        $stmt = $this->pdo->prepare("SELECT template_settings FROM stores WHERE id = ?");
        $stmt->execute([$this->storeId]);
        $json = $stmt->fetchColumn();
        return json_decode($json, true) ?? [];
    }
}
