<?php

namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use ZipArchive;
use Carbon\Carbon;

class ArchiviSistemaController extends Controller
{
    /**
     * Mostra la dashboard di gestione archivi di sistema
     */
    public function index()
    {
        // Statistiche archivi
        $stats = [
            'comuni_count' => DB::table('comuni_italiani')->count(),
            'last_import' => DB::table('import_logs')
                ->where('tipo', 'comuni_italiani')
                ->latest()
                ->value('created_at'),
            'storage_size' => $this->getArchiveStorageSize(),
            'available_archives' => $this->getAvailableArchives()
        ];

        return view('superadmin.archivi.index', compact('stats'));
    }

    /**
     * Gestione archivio comuni italiani
     */
    public function comuniItaliani(Request $request)
    {
        $query = DB::table('comuni_italiani');

        // Filtri di ricerca
        if ($request->filled('search_nome')) {
            $query->where('denominazione', 'like', '%' . $request->search_nome . '%');
        }

        if ($request->filled('search_provincia')) {
            $query->where('provincia_codice', 'like', '%' . $request->search_provincia . '%');
        }

        if ($request->filled('search_regione')) {
            $query->where('regione_denominazione', 'like', '%' . $request->search_regione . '%');
        }

        if ($request->filled('search_cap')) {
            $query->where('cap', 'like', '%' . $request->search_cap . '%');
        }

        // Export CSV
        if ($request->get('export') === 'csv') {
            return $this->exportComuniCSV($query);
        }

        $comuni = $query->orderBy('denominazione')->paginate(50);

        return view('superadmin.archivi.comuni', compact('comuni'));
    }

    /**
     * Export comuni in formato CSV
     */
    private function exportComuniCSV($query)
    {
        $comuni = $query->get();
        
        $filename = 'comuni_italiani_' . date('Y-m-d_H-i') . '.csv';
        
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ];

        $callback = function() use ($comuni) {
            $file = fopen('php://output', 'w');
            
            // Header CSV
            fputcsv($file, [
                'Codice ISTAT',
                'Denominazione',
                'Denominazione Straniera',
                'Codice Catastale',
                'CAP',
                'Provincia Codice',
                'Provincia Denominazione',
                'Regione Codice',
                'Regione Denominazione'
            ], ';');

            // Dati
            foreach ($comuni as $comune) {
                fputcsv($file, [
                    $comune->codice_istat,
                    $comune->denominazione,
                    $comune->denominazione_straniera,
                    $comune->codice_catastale,
                    $comune->cap,
                    $comune->provincia_codice,
                    $comune->provincia_denominazione,
                    $comune->regione_codice,
                    $comune->regione_denominazione
                ], ';');
            }

            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }

    /**
     * Import ZIP con dati JSON
     */
    public function importZip(Request $request)
    {
        $request->validate([
            'zip_file' => 'required|file|mimes:zip|max:51200', // 50MB max
            'tipo_archivio' => 'required|string|in:comuni_italiani,province,regioni'
        ]);

        try {
            $zipFile = $request->file('zip_file');
            $tipoArchivio = $request->input('tipo_archivio');
            
            // Salva il file ZIP temporaneamente
            $zipPath = $zipFile->storeAs('temp', 'import_' . time() . '.zip');
            $fullZipPath = storage_path('app/' . $zipPath);

            // Estrai e processa il ZIP
            $result = $this->processZipImport($fullZipPath, $tipoArchivio);

            // Cancella il file ZIP dopo l'importazione
            Storage::delete($zipPath);

            // Log dell'operazione
            DB::table('import_logs')->insert([
                'tipo' => $tipoArchivio,
                'file_originale' => $zipFile->getClientOriginalName(),
                'records_importati' => $result['imported'],
                'errori' => $result['errors'],
                'user_id' => auth()->id(),
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ]);

            return response()->json([
                'success' => true,
                'message' => "Importazione completata. {$result['imported']} record importati.",
                'data' => $result
            ]);

        } catch (\Exception $e) {
            Log::error('Errore import ZIP: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'message' => 'Errore durante l\'importazione: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Processa il file ZIP e importa i dati
     */
    private function processZipImport($zipPath, $tipo)
    {
        $zip = new ZipArchive;
        $imported = 0;
        $errors = [];

        if ($zip->open($zipPath) === TRUE) {
            // Estrai in una cartella temporanea
            $extractPath = storage_path('app/temp/extract_' . time());
            $zip->extractTo($extractPath);
            $zip->close();

            // Cerca file JSON nella cartella estratta
            $jsonFiles = glob($extractPath . '/*.json');
            
            foreach ($jsonFiles as $jsonFile) {
                $jsonData = json_decode(file_get_contents($jsonFile), true);
                
                if ($jsonData) {
                    $result = $this->importJsonData($jsonData, $tipo);
                    $imported += $result['imported'];
                    $errors = array_merge($errors, $result['errors']);
                }
            }

            // Pulisci la cartella estratta
            $this->deleteDirectory($extractPath);
        } else {
            throw new \Exception('Impossibile aprire il file ZIP');
        }

        return [
            'imported' => $imported,
            'errors' => $errors
        ];
    }

    /**
     * Importa i dati JSON nel database
     */
    private function importJsonData($data, $tipo)
    {
        $imported = 0;
        $errors = [];

        DB::beginTransaction();
        
        try {
            switch ($tipo) {
                case 'comuni_italiani':
                    $imported = $this->importComuniItaliani($data);
                    break;
                
                case 'province':
                    $imported = $this->importProvince($data);
                    break;
                
                case 'regioni':
                    $imported = $this->importRegioni($data);
                    break;
                
                default:
                    throw new \Exception("Tipo archivio non supportato: {$tipo}");
            }

            DB::commit();
            
        } catch (\Exception $e) {
            DB::rollBack();
            $errors[] = $e->getMessage();
        }

        return [
            'imported' => $imported,
            'errors' => $errors
        ];
    }

    /**
     * Importa i comuni italiani
     */
    private function importComuniItaliani($data)
    {
        // Se necessario, svuota la tabella esistente
        DB::table('comuni_italiani')->truncate();
        
        $imported = 0;
        $chunk = [];
        
        foreach ($data as $record) {
            $chunk[] = [
                'codice_istat' => $record['codice_istat'] ?? null,
                'denominazione' => $record['denominazione'] ?? null,
                'denominazione_straniera' => $record['denominazione_straniera'] ?? null,
                'codice_catastale' => $record['codice_catastale'] ?? null,
                'cap' => $record['cap'] ?? null,
                'provincia_codice' => $record['provincia_codice'] ?? null,
                'provincia_denominazione' => $record['provincia_denominazione'] ?? null,
                'regione_codice' => $record['regione_codice'] ?? null,
                'regione_denominazione' => $record['regione_denominazione'] ?? null,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ];
            
            // Inserisci a blocchi di 500 record
            if (count($chunk) >= 500) {
                DB::table('comuni_italiani')->insert($chunk);
                $imported += count($chunk);
                $chunk = [];
            }
        }
        
        // Inserisci il resto
        if (!empty($chunk)) {
            DB::table('comuni_italiani')->insert($chunk);
            $imported += count($chunk);
        }
        
        return $imported;
    }

    /**
     * Importa le province
     */
    private function importProvince($data)
    {
        DB::table('province')->truncate();
        
        $imported = 0;
        foreach ($data as $record) {
            DB::table('province')->insert([
                'codice' => $record['codice'] ?? null,
                'denominazione' => $record['denominazione'] ?? null,
                'sigla' => $record['sigla'] ?? null,
                'regione_codice' => $record['regione_codice'] ?? null,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ]);
            $imported++;
        }
        
        return $imported;
    }

    /**
     * Importa le regioni
     */
    private function importRegioni($data)
    {
        DB::table('regioni')->truncate();
        
        $imported = 0;
        foreach ($data as $record) {
            DB::table('regioni')->insert([
                'codice' => $record['codice'] ?? null,
                'denominazione' => $record['denominazione'] ?? null,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ]);
            $imported++;
        }
        
        return $imported;
    }

    /**
     * Calcola la dimensione dello storage archivi
     */
    private function getArchiveStorageSize()
    {
        $size = 0;
        $directories = ['archives', 'temp'];
        
        foreach ($directories as $dir) {
            $path = storage_path("app/{$dir}");
            if (is_dir($path)) {
                $size += $this->getDirectorySize($path);
            }
        }
        
        return $this->formatBytes($size);
    }

    /**
     * Ottiene gli archivi disponibili
     */
    private function getAvailableArchives()
    {
        return [
            'comuni_italiani' => [
                'nome' => 'Comuni Italiani',
                'descrizione' => 'Archivio completo dei comuni italiani con codici ISTAT',
                'ultima_sincronizzazione' => DB::table('import_logs')
                    ->where('tipo', 'comuni_italiani')
                    ->latest()
                    ->value('created_at')
            ],
            'province' => [
                'nome' => 'Province Italiane',
                'descrizione' => 'Elenco delle province italiane',
                'ultima_sincronizzazione' => null
            ],
            'regioni' => [
                'nome' => 'Regioni Italiane', 
                'descrizione' => 'Elenco delle regioni italiane',
                'ultima_sincronizzazione' => null
            ]
        ];
    }

    /**
     * Cancella ricorsivamente una directory
     */
    private function deleteDirectory($dir)
    {
        if (!is_dir($dir)) return;
        
        $files = array_diff(scandir($dir), ['.', '..']);
        
        foreach ($files as $file) {
            $path = $dir . DIRECTORY_SEPARATOR . $file;
            is_dir($path) ? $this->deleteDirectory($path) : unlink($path);
        }
        
        rmdir($dir);
    }

    /**
     * Calcola la dimensione di una directory
     */
    private function getDirectorySize($path)
    {
        $size = 0;
        
        if (is_dir($path)) {
            $iterator = new \RecursiveIteratorIterator(
                new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS)
            );
            
            foreach ($iterator as $file) {
                $size += $file->getSize();
            }
        }
        
        return $size;
    }

    /**
     * Formatta i byte in formato leggibile
     */
    private function formatBytes($size, $precision = 2)
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        
        for ($i = 0; $size > 1024 && $i < count($units) - 1; $i++) {
            $size /= 1024;
        }
        
        return round($size, $precision) . ' ' . $units[$i];
    }

    /**
     * Sincronizzazione futura con ISTAT
     */
    public function sincronizzaIstat()
    {
        // Placeholder per sincronizzazione automatica con ISTAT
        return response()->json([
            'success' => false,
            'message' => 'Sincronizzazione automatica con ISTAT in sviluppo'
        ]);
    }
}
