<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Product;
use App\Models\Order;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;

class ImportExportController extends Controller
{
    /**
     * Afficher la page d'import/export
     */
    public function index()
    {
        $jobs = [];
        
        // Historique des imports/exports
        if (Storage::exists('imports-exports')) {
            $files = Storage::files('imports-exports');
            foreach ($files as $file) {
                $jobs[] = (object)[
                    'id' => md5($file),
                    'filename' => basename($file),
                    'path' => $file,
                    'size' => $this->formatBytes(Storage::size($file)),
                    'created_at' => Carbon::createFromTimestamp(Storage::lastModified($file)),
                ];
            }
            usort($jobs, fn($a, $b) => $b->created_at <=> $a->created_at);
        }

        return view('admin.import-export.index', compact('jobs'));
    }

    /**
     * Importer des données
     */
    public function import(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'file' => 'required|file|mimes:csv,xlsx,xls,json|max:10240',
            'type' => 'required|in:users,products,categories,orders',
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        try {
            $file = $request->file('file');
            $type = $request->input('type');
            $extension = $file->getClientOriginalExtension();
            
            // Sauvegarder le fichier
            $filename = "{$type}_import_" . now()->format('Y-m-d_H-i-s') . ".{$extension}";
            $path = $file->storeAs('imports-exports', $filename);

            // Lire et traiter le fichier
            $data = $this->parseFile(Storage::path($path), $extension);
            $imported = 0;
            $errors = [];

            switch ($type) {
                case 'users':
                    [$imported, $errors] = $this->importUsers($data);
                    break;
                case 'products':
                    [$imported, $errors] = $this->importProducts($data);
                    break;
                case 'categories':
                    [$imported, $errors] = $this->importCategories($data);
                    break;
            }

            $message = "Import terminé: {$imported} éléments importés.";
            if (count($errors) > 0) {
                $message .= " " . count($errors) . " erreurs rencontrées.";
            }

            return back()->with('success', $message);
        } catch (\Exception $e) {
            \Log::error('Import error: ' . $e->getMessage());
            return back()->with('error', 'Erreur lors de l\'import: ' . $e->getMessage());
        }
    }

    /**
     * Exporter des données
     */
    public function export(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'type' => 'required|in:users,products,categories,orders',
            'format' => 'required|in:csv,json,xlsx',
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        try {
            $type = $request->input('type');
            $format = $request->input('format');
            
            // Récupérer les données
            $data = $this->getExportData($type);
            
            // Créer le fichier
            $filename = "{$type}_export_" . now()->format('Y-m-d_H-i-s') . ".{$format}";
            $content = $this->formatExport($data, $format);
            
            // Sauvegarder
            Storage::put("imports-exports/{$filename}", $content);

            return Storage::download("imports-exports/{$filename}");
        } catch (\Exception $e) {
            \Log::error('Export error: ' . $e->getMessage());
            return back()->with('error', 'Erreur lors de l\'export: ' . $e->getMessage());
        }
    }

    /**
     * Télécharger un fichier
     */
    public function download($filename)
    {
        $path = "imports-exports/{$filename}";
        
        if (Storage::exists($path)) {
            return Storage::download($path);
        }

        return back()->with('error', 'Fichier introuvable.');
    }

    /**
     * Supprimer un job/fichier
     */
    public function destroy($job)
    {
        $files = Storage::files('imports-exports');
        
        foreach ($files as $file) {
            if (md5($file) === $job) {
                Storage::delete($file);
                return back()->with('success', 'Fichier supprimé.');
            }
        }

        return back()->with('error', 'Fichier introuvable.');
    }

    // === Méthodes privées ===

    private function parseFile($path, $extension)
    {
        switch ($extension) {
            case 'json':
                return json_decode(file_get_contents($path), true);
            
            case 'csv':
                $data = [];
                if (($handle = fopen($path, 'r')) !== false) {
                    $headers = fgetcsv($handle);
                    while (($row = fgetcsv($handle)) !== false) {
                        $data[] = array_combine($headers, $row);
                    }
                    fclose($handle);
                }
                return $data;
            
            default:
                throw new \Exception('Format de fichier non supporté');
        }
    }

    private function importUsers(array $data): array
    {
        $imported = 0;
        $errors = [];

        foreach ($data as $row) {
            try {
                if (!isset($row['email'])) continue;
                
                User::updateOrCreate(
                    ['email' => $row['email']],
                    [
                        'name' => $row['name'] ?? 'Sans nom',
                        'phone' => $row['phone'] ?? null,
                        'role' => $row['role'] ?? 'member',
                    ]
                );
                $imported++;
            } catch (\Exception $e) {
                $errors[] = "Ligne {$row['email']}: " . $e->getMessage();
            }
        }

        return [$imported, $errors];
    }

    private function importProducts(array $data): array
    {
        $imported = 0;
        $errors = [];

        foreach ($data as $row) {
            try {
                if (!isset($row['name'])) continue;
                
                Product::updateOrCreate(
                    ['name' => $row['name']],
                    [
                        'price' => $row['price'] ?? 0,
                        'stock' => $row['stock'] ?? 0,
                        'description' => $row['description'] ?? null,
                        'category_id' => $row['category_id'] ?? 1,
                    ]
                );
                $imported++;
            } catch (\Exception $e) {
                $errors[] = "Produit {$row['name']}: " . $e->getMessage();
            }
        }

        return [$imported, $errors];
    }

    private function importCategories(array $data): array
    {
        $imported = 0;
        $errors = [];

        foreach ($data as $row) {
            try {
                if (!isset($row['name'])) continue;
                
                Category::updateOrCreate(
                    ['name' => $row['name']],
                    [
                        'description' => $row['description'] ?? null,
                    ]
                );
                $imported++;
            } catch (\Exception $e) {
                $errors[] = "Catégorie {$row['name']}: " . $e->getMessage();
            }
        }

        return [$imported, $errors];
    }

    private function getExportData(string $type): array
    {
        switch ($type) {
            case 'users':
                return User::select('id', 'name', 'email', 'phone', 'role', 'created_at')
                    ->get()
                    ->toArray();
            
            case 'products':
                return Product::select('id', 'name', 'price', 'stock', 'category_id', 'created_at')
                    ->get()
                    ->toArray();
            
            case 'categories':
                return Category::select('id', 'name', 'description', 'created_at')
                    ->get()
                    ->toArray();
            
            case 'orders':
                return Order::select('id', 'user_id', 'status', 'total', 'created_at')
                    ->with('user:id,name,email')
                    ->get()
                    ->toArray();
            
            default:
                return [];
        }
    }

    private function formatExport(array $data, string $format): string
    {
        switch ($format) {
            case 'json':
                return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
            
            case 'csv':
                if (empty($data)) return '';
                
                $output = fopen('php://temp', 'r+');
                fputcsv($output, array_keys($data[0]));
                foreach ($data as $row) {
                    fputcsv($output, $row);
                }
                rewind($output);
                $content = stream_get_contents($output);
                fclose($output);
                return $content;
            
            default:
                return json_encode($data);
        }
    }

    private function formatBytes($bytes, $precision = 2)
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        $bytes /= pow(1024, $pow);
        return round($bytes, $precision) . ' ' . $units[$pow];
    }
}
