<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Period;
use App\Models\Voter;
use App\Models\VoterCredential;
use Illuminate\Http\Request;
use App\Imports\VotersImport; // <-- Tambahkan ini
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\StreamedResponse;

class VoterController extends Controller
{
    public function index(Request $request)
    {
        // 1. Ambil kata kunci pencarian dari URL, contoh: /voters?search=Ahmad
        $search = $request->query('search');

        $period = Period::where('is_active', 1)->latest()->first();
        
        // 2. Modifikasi query untuk mencari data
        $voters = Voter::query()
            ->when($search, function ($query, $search) {
                // Jika ada kata kunci pencarian, filter data
                return $query->where('name', 'like', "%{$search}%")
                            ->orWhere('nis', 'like', "%{$search}%");
            })
            ->orderBy('class')
            ->orderBy('name')
            ->paginate(20)
            ->withQueryString(); // 3. Agar parameter pencarian tetap ada saat pindah halaman

        $withPin = $period ? VoterCredential::where('period_id', $period->id)->count() : 0;

        // 4. Kirim variabel $search ke view
        return view('admin.voters.index', compact('voters', 'period', 'withPin', 'search'));
    }

    // ====== IMPOR ======

    public function import(Request $request)
    {
        // 1. Perbarui validasi untuk menerima file Excel dan CSV
        $request->validate([
            'csv' => 'required|file|mimes:xlsx,xls,csv|max:20480',
        ]);

        $period = Period::where('is_active',1)->latest()->first();
        if (!$period) {
            return back()->with('error','Harap buat periode aktif terlebih dahulu sebelum mengimpor data.');
        }

        try {
            // 2. Gunakan package Excel untuk mengimpor
            Excel::import(new VotersImport, $request->file('csv'));
            
            return back()->with('status', 'Data pemilih berhasil diimpor.');

        } catch (\Exception $e) {
            // 3. Tangani kemungkinan error
            return back()->with('error', 'Terjadi kesalahan saat mengimpor file. Pastikan format kolom sudah benar (nis, name, class) dan coba lagi. Pesan error: ' . $e->getMessage());
        }
    }

    // ====== GENERATE PIN MASSAL & DOWNLOAD ======
    
    public function generatePins(Request $request)
    {
        $period = Period::where('is_active', 1)->latest()->first();
        if (!$period) {
            return back()->with('error', 'Periode aktif belum ada.');
        }

        $voters = Voter::where('is_active', 1)->get();
        
        // 1. Siapkan dua array kosong
        $credentialsToUpsert = [];
        $generatedForCsv = [];
        $now = now(); // Ambil waktu saat ini sekali saja

        foreach ($voters as $v) {
            $pinPlain = str_pad(random_int(0, 9999), 4, '0', STR_PAD_LEFT); // PIN 4 digit lebih aman
            $pinHashed = bcrypt($pinPlain); // Lakukan hash di sini agar lebih cepat

            // 2. Kumpulkan data untuk database di satu array
            $credentialsToUpsert[] = [
                'voter_id'   => $v->id,
                'period_id'  => $period->id,
                'pin'        => $pinHashed,
                'created_at' => $now,
                'updated_at' => $now,
            ];

            // 3. Kumpulkan data PIN asli untuk diunduh/dicetak
            $generatedForCsv[] = ['nis' => $v->nis, 'name' => $v->name, 'class' => $v->class, 'pin' => $pinPlain];
        }

        // 4. Lakukan SATU operasi database untuk semua data
        if (!empty($credentialsToUpsert)) {
            VoterCredential::upsert(
                $credentialsToUpsert,
                ['voter_id', 'period_id'], // Kolom unik untuk dicocokkan
                ['pin', 'updated_at']      // Kolom yang akan di-update jika data sudah ada
            );
        }

        // 5. Simpan data PIN asli ke session
        $request->session()->put('generated_pins', $generatedForCsv);
        
        return back()->with('status', count($generatedForCsv) . ' PIN berhasil dibuat/diperbarui. Klik "Unduh PIN" atau "Cetak Kartu".');
    }

    public function downloadPins(Request $request): StreamedResponse
    {
        $rows = $request->session()->get('generated_pins', []);
        if (empty($rows)) $rows = [['nis'=>'','name'=>'','class'=>'','pin'=>'(tidak ada data PIN baru)']];

        $callback = function() use ($rows) {
            $out = fopen('php://output', 'w');
            fputcsv($out, ['nis','name','class','pin']);
            foreach ($rows as $r) fputcsv($out, [$r['nis'],$r['name'],$r['class'],$r['pin']]);
            fclose($out);
        };
        return response()->streamDownload($callback, 'pin_pemilih.csv', ['Content-Type'=>'text/csv']);
    }

    // ====== FITUR MANUAL ======
    public function create()
    {
        return view('admin.voters.create');
    }

    public function store(Request $request)
    {
        $request->validate([
            'nis'         => 'required|string|unique:voters,nis',
            'name'        => 'required|string|max:255',
            'class'       => 'nullable|string|max:50',
            'is_active'   => 'required|boolean',
            'generate_pin'=> 'required|boolean',
        ]);

        $voter = Voter::create([
            'nis'       => $request->nis,
            'name'      => $request->name,
            'class'     => $request->class,
            'is_active' => $request->boolean('is_active'),
        ]);

        if ($request->boolean('generate_pin')) {
            $period = Period::where('is_active',1)->latest()->first();
            if ($period && !VoterCredential::where('voter_id',$voter->id)->where('period_id',$period->id)->exists()) {
                $pinPlain = str_pad(random_int(0,9999), 4, '0', STR_PAD_LEFT);
                VoterCredential::create([
                    'voter_id'=>$voter->id, 'period_id'=>$period->id, 'pin'=>$pinPlain
                ]);
                // simpan agar bisa langsung diunduh
                $request->session()->put('generated_pins', [[
                    'nis'=>$voter->nis,'name'=>$voter->name,'class'=>$voter->class,'pin'=>$pinPlain
                ]]);
            }
        }

        return redirect()->route('admin.voters.index')->with('status','Pemilih ditambahkan.');
    }

    public function edit(Voter $voter)
    {
        return view('admin.voters.edit', compact('voter'));
    }

    public function update(Request $request, Voter $voter)
    {
        $request->validate([
            'nis'       => 'required|string|unique:voters,nis,'.$voter->id,
            'name'      => 'required|string|max:255',
            'class'     => 'nullable|string|max:50',
            'is_active' => 'required|boolean',
        ]);

        $voter->update([
            'nis'       => $request->nis,
            'name'      => $request->name,
            'class'     => $request->class,
            'is_active' => $request->boolean('is_active'),
        ]);

        return back()->with('status','Pemilih diupdate.');
    }

    public function destroy(Voter $voter)
    {
        // TAMBAHKAN INI: Hapus semua PIN yang terkait dengan pemilih ini
        $voter->credentials()->delete();
        $voter->delete();
        return back()->with('status','Pemilih dihapus.');
    }


    public function printCards(Request $request)
    {
        // Ambil data pemilih & PIN yang baru dibuat dari session
        $voters = $request->session()->get('generated_pins', []);

        if (empty($voters)) {
            return redirect()->route('admin.voters.index')->with('error', 'Tidak ada data PIN baru untuk dicetak. Silakan generate PIN terlebih dahulu.');
        }

        // Kirim data ke view baru yang akan kita buat
        return view('admin.voters.print-cards', compact('voters'));
    }
    
    public function destroyAll()
    {
        // 1. Hapus semua data relasi (semua PIN)
        // Penting untuk menghapus ini dulu
        VoterCredential::query()->delete();

        // 2. Hapus semua data utama (semua pemilih)
        Voter::query()->delete();

        // 3. Kembalikan ke halaman sebelumnya
        return back()->with('status', 'BERHASIL! Seluruh data pemilih dan data PIN telah dihapus dari database.');
    }

    public function generatePinForOne(Request $request, Voter $voter)
    {
        $period = Period::where('is_active',1)->latest()->first();
        if (!$period) return back()->with('error','Periode aktif belum ada.');
        if (VoterCredential::where('voter_id',$voter->id)->where('period_id',$period->id)->exists()) {
            return back()->with('error','Pemilih ini sudah punya PIN pada periode aktif.');
        }

        $pinPlain = str_pad(random_int(0,9999), 4, '0', STR_PAD_LEFT);
        VoterCredential::create([
            'voter_id'=>$voter->id,
            'period_id'=>$period->id,
            'pin'=>$pinPlain,
        ]);

        $request->session()->put('generated_pins', [[
            'nis'=>$voter->nis,'name'=>$voter->name,'class'=>$voter->class,'pin'=>$pinPlain
        ]]);

        return back()->with('status','PIN diterbitkan. Klik "Unduh PIN" untuk mengunduh CSV.');
    }
}
