<?php

namespace App\Http\Controllers;

use App\Models\Individuo;
use App\Models\Contatto;
use App\Models\Documento;
use App\Models\Comune;
use App\Models\Diocesi;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
use Symfony\Component\HttpFoundation\StreamedResponse;

class IndividuoController extends Controller
{
    public function index(Request $request)
    {
        $this->authorizeRead('individui');
        $individui = Individuo::with('contatti')->orderBy('cognome')->orderBy('nome')->paginate(20);

        $vista = null;

        if ($request->has('vista_id')) {
            $vista = \App\Models\VistaReport::where('id', $request->vista_id)
                ->where('user_id', auth()->id())
                ->first();
        }

        if (!$vista && auth()->check()) {
            $vista = \App\Models\VistaReport::where('user_id', auth()->id())
                ->where('tipo', 'individui')
                ->where('is_default', true)
                ->first();
        }

        $allColumns = [
            ['key' => 'codice', 'label' => 'Codice'],
            ['key' => 'cognome', 'label' => 'Cognome'],
            ['key' => 'nome', 'label' => 'Nome'],
            ['key' => 'email', 'label' => 'Email'],
            ['key' => 'telefono', 'label' => 'Telefono'],
        ];

        $defaultVisible = ['codice', 'cognome', 'nome', 'email', 'telefono'];
        $visibleColumns = $vista && !empty($vista->colonne_visibili)
            ? $vista->colonne_visibili
            : $defaultVisible;

        return view('individui.index', compact('individui', 'vista', 'allColumns', 'visibleColumns'));
    }

    public function exportCSV(Request $request)
    {
        $this->authorizeRead('individui');

        $ids = $request->input('ids', []);
        
        $query = Individuo::with('contatti')->orderBy('cognome')->orderBy('nome');
        
        if (is_array($ids) && !empty($ids)) {
            $query->whereIn('id', array_map('intval', $ids));
        }

        $individui = $query->get();

        $response = new StreamedResponse(function () use ($individui) {
            $handle = fopen('php://output', 'w');
            
            fputcsv($handle, ['Codice', 'Cognome', 'Nome', 'Data Nascita', 'Genere', 'Email', 'Telefono', 'Cellulare', 'Indirizzo', 'CAP', 'Città', 'Provincia', 'Note']);
            
            foreach ($individui as $ind) {
                $email = $ind->contatti->where('tipo', 'email')->where('is_primary', true)->first()
                    ?? $ind->contatti->where('tipo', 'email')->first();
                $telefono = $ind->contatti->where('tipo', 'telefono')->where('is_primary', true)->first()
                    ?? $ind->contatti->where('tipo', 'telefono')->first();
                $cellulare = $ind->contatti->where('tipo', 'cellulare')->where('is_primary', true)->first()
                    ?? $ind->contatti->where('tipo', 'cellulare')->first();

                fputcsv($handle, [
                    $ind->codice_id,
                    $ind->cognome,
                    $ind->nome,
                    $ind->data_nascita?->format('d/m/Y') ?? '',
                    $ind->genere === 'M' ? 'Maschio' : ($ind->genere === 'F' ? 'Femmina' : ''),
                    $email?->valore ?? '',
                    $telefono?->valore ?? '',
                    $cellulare?->valore ?? '',
                    $ind->indirizzo,
                    $ind->cap,
                    $ind->città,
                    $ind->sigla_provincia,
                    $ind->note,
                ]);
            }
            
            fclose($handle);
        });

        $response->headers->set('Content-Type', 'text/csv; charset=utf-8');
        $response->headers->set('Content-Disposition', 'attachment; filename="individui_' . now()->format('Y-m-d') . '.csv"');
        $response->headers->set('Cache-Control', 'no-store');

        return $response;
    }

public function create()
    {
        $this->authorizeWrite('individui');
        $comuni = Comune::orderBy('nome')->get();
        $diocesi = Diocesi::orderBy('nome')->get();
        return view('individui.create', compact('comuni', 'diocesi'));
    }

    public function store(Request $request)
    {
        $this->authorizeWrite('individui');
        $data = $request->validate([
            'cognome' => 'required|string|max:255',
            'nome' => 'required|string|max:255',
            'data_nascita' => 'nullable|date',
            'indirizzo' => 'nullable|string|max:500',
            'cap' => 'nullable|string|max:10',
            'città' => 'nullable|string|max:255',
            'sigla_provincia' => 'nullable|string|max:2',
            'genere' => 'nullable|in:M,F',
            'tipo_documento' => 'nullable|in:carta_identita,patente',
            'numero_documento' => 'nullable|string|max:50',
            'scadenza_documento' => 'nullable|date',
            'note' => 'nullable|string',
        ]);

        $individuo = Individuo::create($data);

        if ($request->has('contatti')) {
            foreach ($request->contatti as $contatto) {
                if (!empty($contatto['tipo']) && !empty($contatto['valore'])) {
                    $individuo->contatti()->create([
                        'tipo' => $contatto['tipo'],
                        'valore' => $contatto['valore'],
                        'etichetta' => $contatto['etichetta'] ?? null,
                        'is_primary' => $contatto['is_primary'] ?? false,
                    ]);
                }
            }
        }

        return redirect()->route('individui.index')->with('success', 'Individuo creato con successo.');
    }

    public function show($individuo)
    {
        $this->authorizeRead('individui');
        $individuo = Individuo::with(['contatti', 'gruppi' => function ($q) {
            $q->withPivot('ruolo_ids', 'ruolo_nel_gruppo', 'data_adesione');
        }, 'avatar'])->findOrFail($individuo);
        return view('individui.show', compact('individuo'));
    }

    public function report($individuo)
    {
        $this->authorizeRead('individui');
        $individuo = Individuo::with(['contatti', 'gruppi', 'documenti', 'eventiResponsabili', 'avatar'])->findOrFail($individuo);
        return view('individui.report', compact('individuo'));
    }

    public function reportStampa(Request $request)
    {
        $this->authorizeRead('individui');
        $ids = explode(',', $request->ids ?? '');
        $individui = Individuo::with(['contatti', 'gruppi', 'documenti', 'eventiResponsabili', 'avatar'])
            ->whereIn('id', $ids)
            ->orderBy('cognome')
            ->orderBy('nome')
            ->get();
        return view('individui.report-multiplo', compact('individui'));
    }

    public function edit($individuo)
    {
        $this->authorizeWrite('individui');
        $individuo = Individuo::with(['contatti', 'gruppi', 'avatar'])->findOrFail($individuo);
        return view('individui.edit', compact('individuo'));
    }

    public function update(Request $request, $individuo)
    {
        $this->authorizeWrite('individui');
        $individuo = Individuo::findOrFail($individuo);
        
        \Log::info('=== INDIVIDUO UPDATE START ===', ['id' => $individuo->id]);
        \Log::info('Request contatti:', ['contatti' => $request->input('contatti'), 'all_keys' => array_keys($request->all())]);
        
        $data = $request->validate([
            'cognome' => 'required|string|max:255',
            'nome' => 'required|string|max:255',
            'data_nascita' => 'nullable|date',
            'indirizzo' => 'nullable|string|max:500',
            'cap' => 'nullable|string|max:10',
            'città' => 'nullable|string|max:255',
            'sigla_provincia' => 'nullable|string|max:2',
            'genere' => 'nullable|in:M,F',
            'tipo_documento' => 'nullable|in:carta_identita,patente',
            'numero_documento' => 'nullable|string|max:50',
            'scadenza_documento' => 'nullable|date',
            'note' => 'nullable|string',
        ]);

        $individuo->update($data);
        
        \Log::info('Individuo dati salvati', ['id' => $individuo->id]);

        $contattiData = $request->input('contatti');
        \Log::info('Contatti ricevuti:', ['contatti' => $contattiData, 'tipo' => gettype($contattiData)]);
        
        $individuo->contatti()->delete();
        \Log::info('Contatti precedenti eliminati, count ora:', ['count' => $individuo->contatti()->count()]);

        if (!empty($contattiData) && is_array($contattiData)) {
            $created = 0;
            foreach ($contattiData as $contatto) {
                if (!empty($contatto['tipo']) && !empty($contatto['valore'])) {
                    $individuo->contatti()->create([
                        'tipo' => $contatto['tipo'],
                        'valore' => $contatto['valore'],
                        'etichetta' => $contatto['etichetta'] ?? null,
                        'is_primary' => !empty($contatto['is_primary']),
                    ]);
                    $created++;
                }
            }
            \Log::info('Contatti creati:', ['count' => $created]);
        }

        return redirect()->route('individui.show', $individuo)->with('success', 'Individuo aggiornato con successo!');
    }

    public function destroy($individuo)
    {
        $this->authorizeDelete('individui');
        $individuo = Individuo::findOrFail($individuo);
        $individuo->delete();
        return redirect()->route('individui.index')->with('success', 'Individuo eliminato.');
    }

    public function elimina(Request $request, $individuo)
    {
        $this->authorizeDelete('individui');
        $individuo = Individuo::findOrFail($individuo);

        $eliminaContatti = filter_var($request->input('elimina_contatti', false), FILTER_VALIDATE_BOOLEAN);
        $eliminaDocumenti = filter_var($request->input('elimina_documenti', false), FILTER_VALIDATE_BOOLEAN);

        if ($eliminaContatti) {
            $individuo->contatti()->delete();
        }

        if ($eliminaDocumenti) {
            foreach ($individuo->documenti as $documento) {
                if ($documento->file_path && file_exists(storage_path('app/public/' . $documento->file_path))) {
                    unlink(storage_path('app/public/' . $documento->file_path));
                }
            }
            $individuo->documenti()->delete();
        }

        $individuo->delete();

        return redirect()->route('individui.index')->with('success', 'Individuo eliminato con successo.');
    }

    public function massElimina(Request $request)
    {
        $this->authorizeDelete('individui');
        
        $ids = $request->input('ids', []);
        if (!is_array($ids) || empty($ids)) {
            return redirect()->route('individui.index')->with('error', 'Nessun individuo selezionato.');
        }

        $eliminaContatti = filter_var($request->input('elimina_contatti', false), FILTER_VALIDATE_BOOLEAN);
        $eliminaDocumenti = filter_var($request->input('elimina_documenti', false), FILTER_VALIDATE_BOOLEAN);

        $individui = Individuo::whereIn('id', $ids)->get();
        
        foreach ($individui as $individuo) {
            if ($eliminaContatti) {
                $individuo->contatti()->delete();
            }

            if ($eliminaDocumenti) {
                foreach ($individuo->documenti as $documento) {
                    if ($documento->file_path && file_exists(storage_path('app/public/' . $documento->file_path))) {
                        unlink(storage_path('app/public/' . $documento->file_path));
                    }
                }
                $individuo->documenti()->delete();
            }

            $individuo->delete();
        }

        return redirect()->route('individui.index')->with('success', count($individui) . ' individui eliminati con successo.');
    }

    public function elementiCollegati($individuo)
    {
        $individuo = Individuo::findOrFail($individuo);

        return response()->json([
            'contatti' => $individuo->contatti()->count(),
            'gruppi' => $individuo->gruppi()->count(),
            'documenti' => $individuo->documenti()->count(),
            'eventi' => $individuo->eventiResponsabili()->count(),
        ]);
    }

public function emailList(Request $request)
    {
        $this->authorizeRead('individui');
        $ids = $request->input('ids', '');
        $idArray = array_filter(array_map('intval', explode(',', $ids)));

        if (empty($idArray)) {
            return response()->json([]);
        }

        $individui = Individuo::with('contatti')->whereIn('id', $idArray)->get();

        $result = [];
        foreach ($individui as $ind) {
            $emails = $ind->contatti->where('tipo', 'email')->pluck('valore')->toArray();
            $result[] = [
                'id' => $ind->id,
                'codice_id' => $ind->codice_id,
                'cognome' => $ind->cognome,
                'nome' => $ind->nome,
                'email' => count($emails) === 1 ? $emails[0] : null,
                'emails' => $emails,
                'email_count' => count($emails)
            ];
        }

        return response()->json($result);
    }

    public function allIndividui()
    {
        $this->authorizeRead('individui');
        $individui = Individuo::select('id', 'codice_id', 'cognome', 'nome')
            ->orderBy('cognome')
            ->orderBy('nome')
            ->get();
        return response()->json($individui);
    }

    public function import()
    {
        $this->authorizeWrite('individui');
        return view('individui.import');
    }

    public function importStore(Request $request)
    {
        $this->authorizeWrite('individui');
        $request->validate([
            'file' => 'required|file|mimes:csv,txt',
        ]);

        $file = $request->file('file');
        $handle = fopen($file->path(), 'r');
        $header = fgetcsv($handle, 1000, ',');

        $imported = 0;
        $skipped = 0;
        $errors = [];
        $rowNumber = 1;

        while (($row = fgetcsv($handle, 1000, ',')) !== false) {
            $rowNumber++;

            if (count($row) < count($header)) {
                $skipped++;
                continue;
            }

            $data = array_combine($header, $row);

            if ($data === false) {
                $skipped++;
                continue;
            }

            $cognome = trim($data['cognome'] ?? '');
            $nome = trim($data['nome'] ?? '');

            if (empty($cognome) || empty($nome)) {
                $skipped++;
                continue;
            }

            try {
                $individuo = Individuo::create([
                    'cognome' => $cognome,
                    'nome' => $nome,
                    'data_nascita' => !empty(trim($data['data_nascita'] ?? '')) ? trim($data['data_nascita']) : null,
                    'indirizzo' => !empty(trim($data['indirizzo'] ?? '')) ? trim($data['indirizzo']) : null,
                    'cap' => !empty(trim($data['cap'] ?? '')) ? trim($data['cap']) : null,
                    'città' => !empty(trim($data['città'] ?? '')) ? trim($data['città']) : null,
                    'sigla_provincia' => !empty(trim($data['sigla_provincia'] ?? '')) ? trim($data['sigla_provincia']) : null,
                    'genere' => !empty(trim($data['genere'] ?? '')) ? strtoupper(trim($data['genere'])) : null,
                    'tipo_documento' => !empty(trim($data['tipo_documento'] ?? '')) ? trim($data['tipo_documento']) : null,
                    'numero_documento' => !empty(trim($data['numero_documento'] ?? '')) ? trim($data['numero_documento']) : null,
                    'scadenza_documento' => !empty(trim($data['scadenza_documento'] ?? '')) ? trim($data['scadenza_documento']) : null,
                    'note' => !empty(trim($data['note'] ?? '')) ? trim($data['note']) : null,
                ]);

                for ($i = 1; $i <= 2; $i++) {
                    $tipoKey = 'contatto_' . $i . '_tipo';
                    $valoreKey = 'contatto_' . $i . '_valore';
                    $etichettaKey = 'contatto_' . $i . '_etichetta';

                    $tipo = trim($data[$tipoKey] ?? '');
                    $valore = trim($data[$valoreKey] ?? '');

                    if (!empty($tipo) && !empty($valore)) {
                        $individuo->contatti()->create([
                            'tipo' => $tipo,
                            'valore' => $valore,
                            'etichetta' => !empty(trim($data[$etichettaKey] ?? '')) ? trim($data[$etichettaKey]) : null,
                            'is_primary' => $i === 1,
                        ]);
                    }
                }

                $imported++;
            } catch (\Exception $e) {
                $errors[] = 'Errore riga ' . $rowNumber . ': ' . $e->getMessage();
            }
        }

        fclose($handle);

        $message = 'Importati ' . $imported . ' individui.';
        if ($skipped > 0) {
            $message .= ' Saltate ' . $skipped . ' righe (vuote o incomplete).';
        }
        if (count($errors) > 0) {
            return back()->with('error', $message . ' Errori: ' . implode('; ', $errors));
        }

        return redirect()->route('individui.index')->with('success', $message);
    }

    public function downloadTemplate()
    {
        $this->authorizeRead('individui');
        $headers = ['cognome', 'nome', 'data_nascita', 'indirizzo', 'cap', 'città', 'sigla_provincia', 'genere', 'tipo_documento', 'numero_documento', 'scadenza_documento', 'note', 'contatto_1_tipo', 'contatto_1_valore', 'contatto_1_etichetta', 'contatto_2_tipo', 'contatto_2_valore', 'contatto_2_etichetta'];

        $example = [
            'Rossi',
            'Mario',
            '1990-05-15',
            'Via Roma 10',
            '00100',
            'Roma',
            'RM',
            'M',
            'carta_identita',
            'AB123456',
            '2030-05-15',
            'Socio fondatore',
            'email',
            'mario.rossi@email.com',
            'personale',
            'cellulare',
            '3331234567',
            'lavoro',
        ];

        $csv = implode(',', $headers) . "\n" . implode(',', $example);

        return response($csv, 200, [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="template_individui.csv"',
        ]);
    }

    public function uploadAvatar(Request $request, $individuo)
    {
        $this->authorizeWrite('individui');
        $individuo = Individuo::findOrFail($individuo);

        $request->validate([
            'avatar' => 'required|image|mimes:jpeg,jpg,png,gif|max:2048',
        ]);

        $file = $request->file('avatar');

        $oldAvatar = $individuo->avatar;
        if ($oldAvatar) {
            if (Storage::disk('local')->exists($oldAvatar->file_path)) {
                Storage::disk('local')->delete($oldAvatar->file_path);
            }
            $oldAvatar->delete();
        }

        $path = $file->store('avatars', 'local');

        $avatar = Documento::create([
            'tenant_id' => $individuo->tenant_id,
            'nome_file' => $file->getClientOriginalName(),
            'file_path' => $path,
            'tipo' => 'upload',
            'tipologia' => 'avatar',
            'visibilita' => 'individuo',
            'visibilita_target_id' => $individuo->id,
            'visibilita_target_type' => Individuo::class,
            'mime_type' => $file->getMimeType(),
            'dimensione' => $file->getSize(),
            'user_id' => auth()->id(),
        ]);

        return response()->json([
            'success' => true,
            'avatar_url' => url('/individui/' . $individuo->id . '/avatar'),
            'avatar_id' => $avatar->id,
        ]);
    }

    public function getAvatar($individuo)
    {
        $this->authorizeRead('individui');
        $individuo = Individuo::findOrFail($individuo);
        $avatar = $individuo->avatar;

        if (!$avatar || !Storage::disk('local')->exists($avatar->file_path)) {
            abort(404);
        }

        return response(
            Storage::disk('local')->get($avatar->file_path),
            200,
            ['Content-Type' => $avatar->mime_type]
        );
    }

    public function deleteAvatar($individuo)
    {
        $this->authorizeDelete('individui');
        $individuo = Individuo::findOrFail($individuo);
        $avatar = $individuo->avatar;

        if (!$avatar) {
            return response()->json(['success' => false, 'message' => 'Nessun avatar da eliminare']);
        }

        if (Storage::disk('local')->exists($avatar->file_path)) {
            Storage::disk('local')->delete($avatar->file_path);
        }

        $avatar->delete();

        return response()->json(['success' => true]);
    }
}