<?php
// app/Http/Controllers/AdminController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash; // Add this import
use App\Models\Registration;
use App\Models\Setting;
use App\Models\Holiday;
use App\Exports\RegistrationsExport;
use Maatwebsite\Excel\Facades\Excel;
use Carbon\Carbon; // Tambahkan ini

class AdminController extends Controller
{
    public function dashboard(Request $request)
    {
        $search = $request->input('search', '');
        
        // Get registrations count
        $registrationsToday = Registration::whereDate('visit_date', Carbon::today())->count();
        $totalRegistrationsThisMonth = Registration::whereBetween('visit_date', [
            Carbon::now()->startOfMonth(),
            Carbon::now()->endOfMonth()
        ])->count();

        // Get today's registrations with search and pagination
        $todayRegistrations = Registration::whereDate('visit_date', Carbon::today())
            ->when($search, function($query) use ($search) {
                $query->where(function($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('nik', 'like', "%{$search}%")
                      ->orWhere('booking_code', 'like', "%{$search}%");
                });
            })
            ->orderBy('visit_time')
            ->paginate(10);
            
        // Data antrian online dan offline dari tabel transaksi
        $today = Carbon::today()->format('Y-m-d');
        
        // Hitung jumlah antrian online dan offline
        $onlineQueueToday = \DB::table('transaksi')
            ->whereDate('waktudatang', $today)
            ->where('id_online', '>', 0)
            ->count();
            
        $offlineQueueToday = \DB::table('transaksi')
            ->whereDate('waktudatang', $today)
            ->where('id_online', 0)
            ->count();
            
        // Ambil data antrian online dan offline untuk ditampilkan di tabel
        $onlineQueues = \DB::table('transaksi')
            ->whereDate('waktudatang', $today)
            ->where('id_online', '>', 0)
            ->orderBy('waktudatang')
            ->limit(15)
            ->get();
            
        $offlineQueues = \DB::table('transaksi')
            ->whereDate('waktudatang', $today)
            ->where('id_online', 0)
            ->orderBy('waktudatang')
            ->limit(15)
            ->get();
            
        // Hitung statistik untuk diagram status
        $servedCount = \DB::table('transaksi')
            ->whereDate('waktudatang', $today)
            ->where('status', 1)
            ->count();
            
        $waitingCount = \DB::table('transaksi')
            ->whereDate('waktudatang', $today)
            ->where('status', 0)
            ->count();
            
        $priorityCount = \DB::table('transaksi')
            ->whereDate('waktudatang', $today)
            ->where('priority', 1)
            ->count();
            
        // Data untuk grafik 7 hari terakhir
        $lastSevenDays = [];
        $onlineStats = [];
        $offlineStats = [];
        
        for ($i = 6; $i >= 0; $i--) {
            $date = Carbon::today()->subDays($i);
            $lastSevenDays[] = $date->format('d/m');
            
            $onlineStats[] = \DB::table('transaksi')
                ->whereDate('waktudatang', $date->format('Y-m-d'))
                ->where('id_online', '>', 0)
                ->count();
                
            $offlineStats[] = \DB::table('transaksi')
                ->whereDate('waktudatang', $date->format('Y-m-d'))
                ->where('id_online', 0)
                ->count();
        }
        
        // Data awal untuk tabel statistik
        $dailyStats = \DB::table('transaksi')
            ->select(
                \DB::raw('DATE(waktudatang) as date'),
                \DB::raw('SUM(CASE WHEN id_online > 0 THEN 1 ELSE 0 END) as online'),
                \DB::raw('SUM(CASE WHEN id_online = 0 THEN 1 ELSE 0 END) as offline'),
                \DB::raw('SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as served'),
                \DB::raw('SUM(CASE WHEN priority = 1 THEN 1 ELSE 0 END) as priority')
            )
            ->groupBy(\DB::raw('DATE(waktudatang)'))
            ->orderBy('date', 'desc')
            ->limit(10)
            ->get();

        return view('admin.dashboard', compact(
            'search',
            'registrationsToday', 
            'totalRegistrationsThisMonth',
            'todayRegistrations',
            'onlineQueueToday',
            'offlineQueueToday',
            'onlineQueues',
            'offlineQueues',
            'servedCount',
            'waitingCount',
            'priorityCount',
            'lastSevenDays',
            'onlineStats',
            'offlineStats',
            'dailyStats'
        ));
    }

    public function loadStatistics(Request $request)
    {
        $page = $request->input('page', 1);
        $periode = $request->input('periode', 'daily');
        $perPage = 15;
        
        // Database query
        $query = \DB::table('transaksi')
            ->select(
                \DB::raw('DATE(waktudatang) as date'),
                \DB::raw('SUM(CASE WHEN id_online > 0 THEN 1 ELSE 0 END) as online'),
                \DB::raw('SUM(CASE WHEN id_online = 0 THEN 1 ELSE 0 END) as offline'),
                \DB::raw('SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as served'),
                \DB::raw('SUM(CASE WHEN priority = 1 THEN 1 ELSE 0 END) as priority')
            );
        
        // Apply filters based on period
        if ($periode === 'daily') {
            $query->groupBy(\DB::raw('DATE(waktudatang)'));
        } elseif ($periode === 'weekly') {
            $query->groupBy(\DB::raw('YEARWEEK(waktudatang)'))
                ->select(
                    \DB::raw('DATE(MIN(waktudatang)) as date'),
                    \DB::raw('CONCAT("Minggu ", WEEK(waktudatang), " ", YEAR(waktudatang)) as period'),
                    \DB::raw('SUM(CASE WHEN id_online > 0 THEN 1 ELSE 0 END) as online'),
                    \DB::raw('SUM(CASE WHEN id_online = 0 THEN 1 ELSE 0 END) as offline'),
                    \DB::raw('SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as served'),
                    \DB::raw('SUM(CASE WHEN priority = 1 THEN 1 ELSE 0 END) as priority')
                );
        } elseif ($periode === 'monthly') {
            $query->groupBy(\DB::raw('YEAR(waktudatang), MONTH(waktudatang)'))
                ->select(
                    \DB::raw('DATE(MIN(waktudatang)) as date'),
                    \DB::raw('CONCAT(MONTHNAME(waktudatang), " ", YEAR(waktudatang)) as period'),
                    \DB::raw('SUM(CASE WHEN id_online > 0 THEN 1 ELSE 0 END) as online'),
                    \DB::raw('SUM(CASE WHEN id_online = 0 THEN 1 ELSE 0 END) as offline'),
                    \DB::raw('SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as served'),
                    \DB::raw('SUM(CASE WHEN priority = 1 THEN 1 ELSE 0 END) as priority')
                );
        }
        
        // Order and paginate
        $stats = $query->orderBy('date', 'desc')
                      ->skip(($page - 1) * $perPage)
                      ->take($perPage)
                      ->get();
        
        // Format dates
        foreach ($stats as $stat) {
            if ($periode === 'daily') {
                $stat->date = Carbon::parse($stat->date)->format('d/m/Y');
            }
        }
        
        return response()->json([
            'data' => $stats,
            'page' => $page,
            'periode' => $periode
        ]);
    }

    public function settings()
    {
        $settings = Setting::pluck('value', 'key')->all();
        $holidays = Holiday::orderBy('date')->get();
        return view('admin.settings', compact('settings', 'holidays'));
    }

    public function updateSettings(Request $request)
    {
        $request->validate([
            'max_daily_queue' => 'required|numeric|min:1',
            'old_password' => 'nullable',
            'new_password' => 'nullable|min:6|confirmed|required_with:old_password'
        ]);

        // Update max queue setting
        Setting::updateOrCreate(
            ['key' => 'max_daily_queue'],
            ['value' => $request->max_daily_queue]
        );

        // Update password if provided
        if ($request->filled('old_password')) {
            if (!Hash::check($request->old_password, Auth::guard('admin')->user()->password)) {
                return back()->withErrors(['old_password' => 'Password lama tidak sesuai']);
            }

            $admin = Auth::guard('admin')->user();
            $admin->password = Hash::make($request->new_password);
            $admin->save();
        }

        return back()->with('success', 'Pengaturan berhasil diperbarui');
    }    public function storeHoliday(Request $request)
    {
        $request->validate([
            'start_date' => 'required|date|after_or_equal:today',
            'end_date' => 'required|date|after_or_equal:start_date',
            'description' => 'required'
        ], [
            'end_date.after_or_equal' => 'Tanggal akhir harus sama dengan atau setelah tanggal mulai'
        ]);

        // For backwards compatibility, store the start_date in the date field as well
        $holidayData = [
            'date' => $request->start_date, // Keep the date field for backward compatibility
            'start_date' => $request->start_date,
            'end_date' => $request->end_date,
            'description' => $request->description
        ];
        
        Holiday::create($holidayData);
        return back()->with('success', 'Rentang hari libur berhasil ditambahkan');
    }

    public function deleteHoliday($id)
    {
        Holiday::destroy($id);
        return back()->with('success', 'Hari libur berhasil dihapus');
    }

    public function reports(Request $request)
    {
        $reportType = $request->input('report_type', 'online_registration');
        
        // Default to online registrations if no report type is selected
        if ($reportType === 'online_registration' || empty($reportType)) {
            $query = Registration::query();

            // Apply month and year filters if provided
            if ($request->filled('month') || $request->filled('year')) {
                if ($request->filled('month') && $request->filled('year')) {
                    $query->whereYear('visit_date', $request->year)
                          ->whereMonth('visit_date', $request->month);
                } elseif ($request->filled('month')) {
                    $query->whereMonth('visit_date', $request->month);
                } elseif ($request->filled('year')) {
                    $query->whereYear('visit_date', $request->year);
                }
            } else {
                // Date range filter if month/year not specified
                if ($request->filled('start_date')) {
                    $query->whereDate('visit_date', '>=', $request->start_date);
                }
                if ($request->filled('end_date')) {
                    $query->whereDate('visit_date', '<=', $request->end_date);
                }
            }

            // Search filter
            if ($request->filled('search')) {
                $search = $request->search;
                $query->where(function($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('nik', 'like', "%{$search}%")
                      ->orWhere('booking_code', 'like', "%{$search}%");
                });
            }

            $registrations = $query->orderBy('visit_date', 'desc')
                                  ->orderBy('visit_time', 'asc')
                                  ->paginate(15);
            
            $transactions = null;
        } else {
            // Queue reports (all, online, offline)
            $query = \DB::table('transaksi');
            
            // Apply specific filters based on queue type
            if ($reportType === 'online_queue') {
                $query->where('id_online', '>', 0);
            } elseif ($reportType === 'offline_queue') {
                $query->where('id_online', 0);
            }
            
            // Apply month and year filters if provided
            if ($request->filled('month') || $request->filled('year')) {
                if ($request->filled('month') && $request->filled('year')) {
                    $query->whereYear('waktudatang', $request->year)
                          ->whereMonth('waktudatang', $request->month);
                } elseif ($request->filled('month')) {
                    $query->whereMonth('waktudatang', $request->month);
                } elseif ($request->filled('year')) {
                    $query->whereYear('waktudatang', $request->year);
                }
            } else {
                // Date range filter if month/year not specified
                if ($request->filled('start_date')) {
                    $query->whereDate('waktudatang', '>=', $request->start_date);
                }
                if ($request->filled('end_date')) {
                    $query->whereDate('waktudatang', '<=', $request->end_date);
                }
            }

            // Search filter
            if ($request->filled('search')) {
                $search = $request->search;
                $query->where(function($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('nik', 'like', "%{$search}%")
                      ->orWhere('booking_code', 'like', "%{$search}%")
                      ->orWhere('nomorantrian', 'like', "%{$search}%");
                });
            }

            $transactions = $query->orderBy('waktudatang', 'desc')
                                ->paginate(15);
            
            $registrations = null;
        }

        return view('admin.reports', compact('registrations', 'transactions'));
    }

    public function exportReport(Request $request)
    {
        $reportType = $request->report_type ?? 'online_registration';
        $startDate = $request->start_date;
        $endDate = $request->end_date;
        $search = $request->search;
        
        $filename = 'laporan-';
        
        if ($reportType == 'online_registration') {
            $filename .= 'pendaftaran-online';
            return Excel::download(
                new RegistrationsExport($startDate, $endDate, $search, null, $reportType),
                $filename . '.xlsx'
            );
        } else {
            // For queue reports (all, online, offline)
            if ($reportType == 'all_queue') {
                $filename .= 'antrian-semua';
            } elseif ($reportType == 'online_queue') {
                $filename .= 'antrian-online';
            } elseif ($reportType == 'offline_queue') {
                $filename .= 'antrian-offline';
            }
            
            return Excel::download(
                new RegistrationsExport($startDate, $endDate, $search, null, $reportType),
                $filename . '.xlsx'
            );
        }
    }

    public function checkQuota($date)
    {
        // Set timezone explicitly
        date_default_timezone_set('Asia/Jakarta');
        
        // Convert date to Jakarta timezone for comparison
        $jakartaDate = Carbon::parse($date)
            ->timezone('Asia/Jakarta')
            ->startOfDay();

        // Check holiday using Jakarta date
        if(Holiday::whereDate('date', $jakartaDate->format('Y-m-d'))->exists()) {
            return response()->json(['available' => false, 'message' => 'Hari Libur']);
        }

        $maxDaily = Setting::where('key', 'max_daily_queue')->first()->value ?? 50;
        $count = Registration::whereDate('visit_date', $jakartaDate->format('Y-m-d'))->count();
        
        return response()->json([
            'available' => $count < $maxDaily,
            'date' => $jakartaDate->format('Y-m-d'), // Debug info
            'count' => $count,
            'maxDaily' => $maxDaily
        ]);
    }

    public function logout(Request $request)
    {
        Auth::guard('admin')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();
        
        return redirect('/'); // Redirect to home page
    }

    public function loginForm()
    {
        if (Auth::guard('admin')->check()) {
            return redirect()->route('admin.dashboard');
        }
        return view('admin.login');
    }

    public function login(Request $request)
    {
        $credentials = $request->validate([
            'username' => 'required',
            'password' => 'required'
        ]);

        if (Auth::guard('admin')->attempt($credentials)) {
            $request->session()->regenerate();
            return redirect()->intended(route('admin.dashboard'));
        }

        return back()->withErrors([
            'username' => 'Username atau password salah.',
        ]);
    }    public function serveKtpImage(Registration $registration)
    {
    if (!Auth::guard('admin')->check()) {
        return redirect()->route('admin.login');
    }

    if (!$registration->ktp_image) {
        abort(404);
    }

    // Check if the image is stored as base64 with data URI prefix
    if (strpos($registration->ktp_image, 'data:image') === 0) {
        // It's a base64 image with prefix, serve it directly
        $imageData = $registration->ktp_image;
        list($type, $data) = explode(';', $imageData);
        list(, $data) = explode(',', $data);
        $data = base64_decode($data);
        
        // Get mime type from the base64 string
        $mimeType = substr($type, 5); // Remove "data:" prefix
        
        return response($data)
            ->header('Content-Type', $mimeType)
            ->header('Content-Disposition', 'inline; filename="ktp_' . $registration->nik . '.jpg"');
    } 
    // Check if it's a plain base64 string (new format without prefix)
    else if (preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $registration->ktp_image)) {
        // It's a plain base64 string, decode it
        $data = base64_decode($registration->ktp_image);
        
        // Use jpeg as default mime type for base64 images
        $mimeType = 'image/jpeg';
        
        return response($data)
            ->header('Content-Type', $mimeType)
            ->header('Content-Disposition', 'inline; filename="ktp_' . $registration->nik . '.jpg"');
    } 
    else {
        // It's a file path (for backward compatibility)
        $path = storage_path('app/private/' . $registration->ktp_image);

        if (!file_exists($path)) {
            abort(404);
        }

        return response()->file($path);
    }
}

public function downloadKtp(Registration $registration)
{
    if (!Auth::guard('admin')->check()) {
        return redirect()->route('admin.login');
    }

    if (!$registration->ktp_image) {
        return back()->with('error', 'File KTP tidak ditemukan');
    }

    // Check if the image is stored as base64 with data URI prefix
    if (strpos($registration->ktp_image, 'data:image') === 0) {
        // It's a base64 image with prefix, need to decode and serve it
        list($type, $data) = explode(';', $registration->ktp_image);
        list(, $data) = explode(',', $data);
        $data = base64_decode($data);
        
        // Get mime type from the base64 string
        $mimeType = substr($type, 5); // Remove "data:" prefix
        $extension = explode('/', $mimeType)[1] ?? 'jpg';
        
        $filename = 'ktp_' . $registration->nik . '.' . $extension;
        
        return response($data)
            ->header('Content-Type', $mimeType)
            ->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
    } 
    // Check if it's a plain base64 string (new format without prefix)
    else if (preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $registration->ktp_image)) {
        // It's a plain base64 string, decode it
        $data = base64_decode($registration->ktp_image);
        
        // Use jpeg as default mime type for base64 images
        $mimeType = 'image/jpeg';
        $extension = 'jpg';
        
        $filename = 'ktp_' . $registration->nik . '.' . $extension;
        
        return response($data)
            ->header('Content-Type', $mimeType)
            ->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
    } 
    else {
        // It's a file path (for backward compatibility)
        $path = storage_path('app/private/' . $registration->ktp_image);

        if (!file_exists($path)) {
            return back()->with('error', 'File KTP tidak ditemukan');
        }

        return response()->download($path, basename($registration->ktp_image));
    }
}

public function serveTransactionKtpImage($id)
{
    if (!Auth::guard('admin')->check()) {
        return redirect()->route('admin.login');
    }

    $transaction = \DB::table('transaksi')->where('id', $id)->first();

    if (!$transaction || !$transaction->ktp_image) {
        abort(404);
    }

    // Fix path construction
    $path = storage_path('app/private/' . $transaction->ktp_image);

    // Handle absolute paths in database (for offline registrations)
    if (substr($transaction->ktp_image, 1, 1) === ':' || substr($transaction->ktp_image, 0, 1) === '/') {
        $path = $transaction->ktp_image;
    }

    if (!file_exists($path)) {
        abort(404);
    }

    return response()->file($path);
}

public function downloadTransactionKtp($id)
{
    if (!Auth::guard('admin')->check()) {
        return redirect()->route('admin.login');
    }

    $transaction = \DB::table('transaksi')->where('id', $id)->first();

    if (!$transaction || !$transaction->ktp_image) {
        return back()->with('error', 'File KTP tidak ditemukan');
    }

    // Fix path construction
    $path = storage_path('app/private/' . $transaction->ktp_image);

    // Handle absolute paths in database (for offline registrations)
    if (substr($transaction->ktp_image, 1, 1) === ':' || substr($transaction->ktp_image, 0, 1) === '/') {
        $path = $transaction->ktp_image;
    }

    if (!file_exists($path)) {
        return back()->with('error', 'File KTP tidak ditemukan');
    }

    return response()->download($path, basename($transaction->ktp_image));
}

public function downloadKtpZip(Request $request)
{
    if (!Auth::guard('admin')->check()) {
        return redirect()->route('admin.login');
    }

    $reportType = $request->input('report_type', 'online_registration');
    $month = $request->input('month');
    $year = $request->input('year');
    $startDate = $request->input('start_date');
    $endDate = $request->input('end_date');

    // Create temporary file for the zip
    $zipFileName = 'ktp_images_' . date('YmdHis') . '.zip';
    $zipFilePath = storage_path('app/temp/' . $zipFileName);
    
    // Ensure temp directory exists
    if (!file_exists(storage_path('app/temp'))) {
        mkdir(storage_path('app/temp'), 0755, true);
    }
    
    $zip = new \ZipArchive();
    if ($zip->open($zipFilePath, \ZipArchive::CREATE) !== true) {
        return back()->with('error', 'Tidak dapat membuat file ZIP');
    }

    $filesAdded = 0;

    // Handle different report types
    if ($reportType === 'online_registration') {
        $query = Registration::query()->whereNotNull('ktp_image');
        
        // Apply filters
        $this->applyDateFilters($query, $month, $year, $startDate, $endDate, 'visit_date');
        
        $registrations = $query->get();
        
        foreach ($registrations as $registration) {
            // Check if the image is stored as base64
            if (strpos($registration->ktp_image, 'data:image') === 0) {
                // It's a base64 image, decode it
                list($type, $data) = explode(';', $registration->ktp_image);
                list(, $data) = explode(',', $data);
                $imageData = base64_decode($data);
                
                // Get mime type and extension
                $mimeType = substr($type, 5); // Remove "data:" prefix
                $extension = explode('/', $mimeType)[1] ?? 'jpg';
                
                // Create a temporary file to add to the zip
                $tmpFilename = $registration->name . '_' . $registration->nik . '.' . $extension;
                $tmpFilepath = storage_path('app/temp/' . uniqid() . '_' . $tmpFilename);
                file_put_contents($tmpFilepath, $imageData);
                
                // Add to zip
                $zip->addFile($tmpFilepath, $tmpFilename);
                $filesAdded++;
                
                // Register the temp file for later deletion
                $tempFiles[] = $tmpFilepath;
            } else {
                // It's a file path (backward compatibility)
                $path = storage_path('app/private/' . $registration->ktp_image);
                
                if (file_exists($path)) {
                    // Create a more descriptive filename within the zip
                    $newFilename = $registration->name . '_' . $registration->nik . '_' . basename($registration->ktp_image);
                    $zip->addFile($path, $newFilename);
                    $filesAdded++;
                }
            }
        }
    } else {
        // Transaction-based report types (queue reports)
        $query = \DB::table('transaksi')->whereNotNull('ktp_image');
        
        // Apply queue type filter
        if ($reportType === 'online_queue') {
            $query->where('id_online', '>', 0);
        } elseif ($reportType === 'offline_queue') {
            $query->where('id_online', 0);
        }
        
        // Apply filters
        $this->applyDateFilters($query, $month, $year, $startDate, $endDate, 'waktudatang');
        
        $transactions = $query->get();
        
        foreach ($transactions as $transaction) {
            // Check if the image is stored as base64 (although transaction table might not use base64 yet)
            if (is_string($transaction->ktp_image) && strpos($transaction->ktp_image, 'data:image') === 0) {
                // It's a base64 image, decode it
                list($type, $data) = explode(';', $transaction->ktp_image);
                list(, $data) = explode(',', $data);
                $imageData = base64_decode($data);
                
                // Get mime type and extension
                $mimeType = substr($type, 5); // Remove "data:" prefix
                $extension = explode('/', $mimeType)[1] ?? 'jpg';
                
                // Create a temporary file to add to the zip
                $tmpFilename = $transaction->name . '_' . $transaction->nik . '.' . $extension;
                $tmpFilepath = storage_path('app/temp/' . uniqid() . '_' . $tmpFilename);
                file_put_contents($tmpFilepath, $imageData);
                
                // Add to zip
                $zip->addFile($tmpFilepath, $tmpFilename);
                $filesAdded++;
                
                // Register the temp file for later deletion
                $tempFiles[] = $tmpFilepath;
            } else {
                // Fix path construction
                $path = storage_path('app/private/' . $transaction->ktp_image);
                
                // Handle absolute paths in database (for offline registrations)
                if (substr($transaction->ktp_image, 1, 1) === ':' || substr($transaction->ktp_image, 0, 1) === '/') {
                    $path = $transaction->ktp_image;
                }
                
                if (file_exists($path)) {
                    // Create a more descriptive filename within the zip
                    $newFilename = $transaction->name . '_' . $transaction->nik . '_' . basename($transaction->ktp_image);
                    $zip->addFile($path, $newFilename);
                    $filesAdded++;
                }
            }
        }
    }

    $zip->close();
    
    // Clean up any temporary files created
    if (!empty($tempFiles)) {
        foreach ($tempFiles as $tempFile) {
            @unlink($tempFile);
        }
    }
    
    if ($filesAdded === 0) {
        // Delete the empty zip file
        @unlink($zipFilePath);
        return back()->with('error', 'Tidak ada file KTP yang ditemukan untuk diunduh');
    }
    
    // Return the zip file as a download
    return response()->download($zipFilePath, $zipFileName)->deleteFileAfterSend(true);
}

/**
 * Apply date filters to a query
 * 
 * @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
 * @param string|null $month
 * @param string|null $year
 * @param string|null $startDate
 * @param string|null $endDate
 * @param string $dateField
 * @return void
 */
protected function applyDateFilters($query, $month, $year, $startDate, $endDate, $dateField)
{
    if ($month || $year) {
        if ($month && $year) {
            $query->whereYear($dateField, $year)
                  ->whereMonth($dateField, $month);
        } elseif ($month) {
            $query->whereMonth($dateField, $month);
        } elseif ($year) {
            $query->whereYear($dateField, $year);
        }
    } else {
        if ($startDate) {
            $query->whereDate($dateField, '>=', $startDate);
        }
        if ($endDate) {
            $query->whereDate($dateField, '<=', $endDate);
        }
    }
}
}