<?php

namespace App\Services;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

/**
 * Service d'export CSV/Excel pour les données admin
 * 
 * Utilisation:
 * return ExportService::toCSV($data, $columns, 'export.csv');
 * return ExportService::toExcel($data, $columns, 'export.xlsx'); // Nécessite PhpSpreadsheet
 */
class ExportService
{
    /**
     * Exporter des données au format CSV
     *
     * @param iterable $data Collection ou array de données
     * @param array $columns Colonnes à exporter ['key' => 'Label', ...]
     * @param string $filename Nom du fichier
     * @param string $delimiter Délimiteur CSV (par défaut ;)
     * @return StreamedResponse
     */
    public static function toCSV(iterable $data, array $columns, string $filename = 'export.csv', string $delimiter = ';'): StreamedResponse
    {
        $headers = [
            'Content-Type' => 'text/csv; charset=UTF-8',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
            'Cache-Control' => 'max-age=0',
        ];

        $callback = function() use ($data, $columns, $delimiter) {
            $file = fopen('php://output', 'w');
            
            // BOM UTF-8 pour Excel
            fprintf($file, chr(0xEF) . chr(0xBB) . chr(0xBF));
            
            // En-têtes
            fputcsv($file, array_values($columns), $delimiter);
            
            // Données
            foreach ($data as $row) {
                $rowData = [];
                foreach (array_keys($columns) as $key) {
                    $value = self::getNestedValue($row, $key);
                    $rowData[] = self::formatValue($value);
                }
                fputcsv($file, $rowData, $delimiter);
            }
            
            fclose($file);
        };

        return Response::stream($callback, 200, $headers);
    }

    /**
     * Exporter des données au format Excel (XLSX)
     * Nécessite PhpSpreadsheet : composer require phpoffice/phpspreadsheet
     * 
     * Si PhpSpreadsheet n'est pas installé, retourne un CSV compatible Excel
     */
    public static function toExcel(iterable $data, array $columns, string $filename = 'export.xlsx'): StreamedResponse
    {
        // Vérifier si PhpSpreadsheet est disponible
        if (!class_exists('\PhpOffice\PhpSpreadsheet\Spreadsheet')) {
            // Fallback vers CSV avec extension xlsx (Excel peut l'ouvrir)
            return self::toCSV($data, $columns, str_replace('.xlsx', '.csv', $filename));
        }

        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        // En-têtes
        $col = 'A';
        foreach (array_values($columns) as $header) {
            $sheet->setCellValue($col . '1', $header);
            $sheet->getStyle($col . '1')->getFont()->setBold(true);
            $col++;
        }

        // Données
        $rowNum = 2;
        foreach ($data as $row) {
            $col = 'A';
            foreach (array_keys($columns) as $key) {
                $value = self::getNestedValue($row, $key);
                $sheet->setCellValue($col . $rowNum, self::formatValue($value));
                $col++;
            }
            $rowNum++;
        }

        // Auto-ajuster la largeur des colonnes
        foreach (range('A', $col) as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }

        // Générer le fichier
        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);

        $headers = [
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
            'Cache-Control' => 'max-age=0',
        ];

        return Response::stream(function() use ($writer) {
            $writer->save('php://output');
        }, 200, $headers);
    }

    /**
     * Obtenir une valeur imbriquée (ex: 'user.name')
     */
    protected static function getNestedValue($item, string $key): mixed
    {
        $keys = explode('.', $key);
        $value = $item;

        foreach ($keys as $k) {
            if (is_array($value)) {
                $value = $value[$k] ?? null;
            } elseif (is_object($value)) {
                $value = $value->{$k} ?? null;
            } else {
                return null;
            }
        }

        return $value;
    }

    /**
     * Formater une valeur pour l'export
     */
    protected static function formatValue(mixed $value): string
    {
        if ($value === null) {
            return '';
        }

        if ($value instanceof \DateTime || $value instanceof \Carbon\Carbon) {
            return $value->format('d/m/Y H:i:s');
        }

        if (is_bool($value)) {
            return $value ? 'Oui' : 'Non';
        }

        if (is_array($value)) {
            return json_encode($value);
        }

        return (string) $value;
    }

    /**
     * Configurations d'export prédéfinies pour les différentes entités
     */
    public static function getExportConfig(string $type): array
    {
        return match($type) {
            'users' => [
                'id' => 'ID',
                'first_name' => 'Prénom',
                'last_name' => 'Nom',
                'email' => 'Email',
                'phone' => 'Téléphone',
                'role' => 'Rôle',
                'is_active' => 'Actif',
                'current_rank' => 'Rang',
                'wallet_balance' => 'Solde Wallet',
                'total_earnings' => 'Gains Totaux',
                'referrer.first_name' => 'Parrain',
                'created_at' => 'Date Inscription',
            ],
            
            'orders' => [
                'id' => 'ID',
                'order_number' => 'N° Commande',
                'user.first_name' => 'Client (Prénom)',
                'user.last_name' => 'Client (Nom)',
                'user.email' => 'Email Client',
                'total_amount' => 'Montant Total',
                'status' => 'Statut',
                'payment_status' => 'Paiement',
                'payment_method' => 'Méthode Paiement',
                'created_at' => 'Date Commande',
            ],
            
            'products' => [
                'id' => 'ID',
                'name' => 'Nom',
                'slug' => 'Slug',
                'price' => 'Prix',
                'stock_quantity' => 'Stock',
                'category.name' => 'Catégorie',
                'seller.shop_name' => 'Vendeur',
                'is_active' => 'Actif',
                'is_featured' => 'En vedette',
                'created_at' => 'Date Création',
            ],
            
            'commissions' => [
                'id' => 'ID',
                'user.first_name' => 'Bénéficiaire',
                'user.last_name' => 'Nom',
                'amount' => 'Montant',
                'type' => 'Type',
                'level' => 'Niveau',
                'status' => 'Statut',
                'order.order_number' => 'Commande',
                'from_user.first_name' => 'Source',
                'created_at' => 'Date',
            ],
            
            'withdrawals' => [
                'id' => 'ID',
                'user.first_name' => 'Demandeur',
                'user.last_name' => 'Nom',
                'amount' => 'Montant',
                'fees' => 'Frais',
                'net_amount' => 'Montant Net',
                'payment_method' => 'Méthode',
                'status' => 'Statut',
                'processed_at' => 'Date Traitement',
                'created_at' => 'Date Demande',
            ],
            
            'sellers' => [
                'id' => 'ID',
                'user.first_name' => 'Prénom',
                'user.last_name' => 'Nom',
                'user.email' => 'Email',
                'shop_name' => 'Nom Boutique',
                'status' => 'Statut',
                'is_verified' => 'Vérifié',
                'commission_rate' => 'Taux Commission',
                'total_sales' => 'Ventes Totales',
                'created_at' => 'Date Inscription',
            ],
            
            'amm_status' => [
                'id' => 'ID',
                'first_name' => 'Prénom',
                'last_name' => 'Nom',
                'email' => 'Email',
                'current_purchases' => 'Achats du Mois',
                'amm_required' => 'AMM Requis',
                'percentage' => '% Progression',
                'is_compliant' => 'Conforme',
                'amm_exemption_until' => 'Exonéré Jusqu\'au',
            ],
            
            default => [],
        };
    }
}
