<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Kegiatan;
use App\Models\KegiatanPartisipan;
use App\Models\Anggota;
use App\Models\User;
use App\Models\JenisKegiatan;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Helpers\CacheHelper;

class KegiatanController extends Controller
{
    /**
     * Clear cache yang terkait dengan data master
     */
    private function clearMasterDataCache()
    {
        CacheHelper::clearMasterDataCache();
    }
    
    /**
     * API untuk mendapatkan data anggota dengan pagination dan filter
     */
    public function getAnggotaPaginated(Request $request)
    {
        try {
            $query = Anggota::where('status_keanggotaan', 'Aktif')
                          ->select(['id', 'nama_lengkap', 'jenis_kelamin', 'ref_jenjang_id', 'upa_id', 'dpc_id', 'dpd_id'])
                          ->with([
                              'refJenjang:ref_jenjang_id,jenjang',
                              'upa:upa_id,nama_upa',
                              'dpc:dpc_id,nama_dpc',
                              'dpd:dpd_id,nama_dpd'
                          ]);
            
            // Apply filters
            if ($request->filled('nama')) {
                $query->where('nama_lengkap', 'like', '%' . $request->nama . '%');
            }
            
            if ($request->filled('jenis_kelamin')) {
                $query->where('jenis_kelamin', $request->jenis_kelamin);
            }
            
            if ($request->filled('dpd')) {
                $query->where('dpd_id', $request->dpd);
            }
            
            if ($request->filled('dpc') && is_array($request->dpc)) {
                $query->whereIn('dpc_id', $request->dpc);
            }
            
            if ($request->filled('upa') && is_array($request->upa)) {
                $query->whereIn('upa_id', $request->upa);
            }
            
            $anggotas = $query->orderBy('nama_lengkap')->paginate(10);
            
            // Get existing partisipan IDs
            $existingPartisipan = collect($request->old_partisipan ?? []);
            
            // Format data untuk JavaScript
            $data = $anggotas->map(function($anggota) use ($existingPartisipan) {
                return [
                    'id' => $anggota->id,
                    'nama_lengkap' => $anggota->nama_lengkap,
                    'jenis_kelamin' => $anggota->jenis_kelamin,
                    'ref_jenjang' => [
                        'jenjang' => $anggota->refJenjang->jenjang ?? 'N/A'
                    ],
                    'ref_grup_upa' => [
                        'nama_grup_upa' => $anggota->refGrupUpa->nama_grup_upa ?? 'N/A'
                    ],
                    'dpc' => [
                        'nama_dpc' => $anggota->dpc->nama_dpc ?? 'N/A'
                    ],
                    'dpd' => [
                        'nama_dpd' => $anggota->dpd->nama_dpd ?? 'N/A'
                    ],
                    'is_checked' => $existingPartisipan->contains($anggota->id)
                ];
            });
            
            return response()->json([
                'data' => $data,
                'current_page' => $anggotas->currentPage(),
                'last_page' => $anggotas->lastPage(),
                'per_page' => $anggotas->perPage(),
                'total' => $anggotas->total(),
                'from' => $anggotas->firstItem(),
                'to' => $anggotas->lastItem()
            ]);
            
        } catch (\Exception $e) {
            \Log::error('Error in getAnggotaPaginated: ' . $e->getMessage());
            return response()->json([
                'error' => 'Error loading data: ' . $e->getMessage()
            ], 500);
        }
    }
    public function index(Request $request)
    {
        $query = Kegiatan::with(['pic', 'picAnggota', 'partisipan', 'jenisKegiatan']);
        
        // Filter berdasarkan jenis
        if ($request->filled('jenis')) {
            $query->where('ref_jenis_kegiatan_id', $request->jenis);
        }
        
        // Filter berdasarkan status
        if ($request->filled('status')) {
            $query->where('status_kegiatan', $request->status);
        }
        
        // Filter berdasarkan tanggal
        if ($request->filled('tanggal_dari')) {
            $query->whereDate('tanggal_kegiatan', '>=', $request->tanggal_dari);
        }
        
        if ($request->filled('tanggal_sampai')) {
            $query->whereDate('tanggal_kegiatan', '<=', $request->tanggal_sampai);
        }
        
        // Search berdasarkan nama kegiatan
        if ($request->filled('search')) {
            $query->where('nama_kegiatan', 'like', '%' . $request->search . '%');
        }
        
        $kegiatans = $query->orderBy('tanggal_kegiatan', 'desc')->paginate(10);
        $jenisKegiatans = cache()->remember('jenis_kegiatan_active', 3600, function() {
            return JenisKegiatan::active()->select('ref_jenis_kegiatan_id', 'nama_jenis_kegiatan')->orderBy('nama_jenis_kegiatan')->get();
        });
        
        return view('kegiatan.index', compact('kegiatans', 'jenisKegiatans'));
    }

    public function create()
    {
        // Get all active anggota for PIC selection
        $anggotas = Anggota::where('status_keanggotaan', 'Aktif')
                          ->select(['id', 'nama_lengkap', 'nomor_identitas_anggota', 'jenis_kelamin', 'ref_jenjang_id', 'upa_id', 'dpc_id', 'dpd_id'])
                          ->with([
                              'refJenjang:ref_jenjang_id,jenjang',
                              'upa:upa_id,nama_upa',
                              'dpc:dpc_id,nama_dpc',
                              'dpd:dpd_id,nama_dpd'
                          ])
                          ->orderBy('nama_lengkap')
                          ->get();
        
        // Cache data yang jarang berubah
        $users = cache()->remember('users_list', 300, function() {
            return User::select(['id', 'name'])->orderBy('name')->get();
        });
        
        $jenisKegiatans = cache()->remember('jenis_kegiatan_active', 600, function() {
            return JenisKegiatan::active()->select(['ref_jenis_kegiatan_id', 'nama_jenis_kegiatan'])->orderBy('nama_jenis_kegiatan')->get();
        });
        
        // Cache data DPD untuk filter - konsisten dengan AnggotaController
        cache()->remember('dpd_active_list', 3600, function() {
            return \App\Models\Dpd::active()->select(['dpd_id', 'nama_dpd'])->get();
        });
        
        return view('kegiatan.create', compact('anggotas', 'users', 'jenisKegiatans'));
    }

    public function store(Request $request)
    {
        // Determine validation rules based on event type
        $eventType = $request->input('event_type', 'single');
        
        $rules = [
            'nama_kegiatan' => 'required|string|max:255',
            'deskripsi' => 'nullable|string',
            'event_type' => 'required|in:single,multi',
            'tempat' => 'required|string|max:500',
            'ref_jenis_kegiatan_id' => 'required',
            'jenis_kegiatan_lainnya' => 'required_if:ref_jenis_kegiatan_id,lainnya|nullable|string|max:255',
            'target_peserta' => 'nullable|integer|min:1',
            'catatan' => 'nullable|string',
            'pic_anggota_id' => 'nullable|exists:tbl_anggota,id',
            'partisipan' => 'nullable|array',
            'partisipan.*' => 'exists:tbl_anggota,id',
            'status_partisipasi' => 'nullable|array',
            'status_partisipasi.*' => 'in:Wajib,Opsional,Undangan',
        ];
        
        // Add conditional validation rules based on event type
        if ($eventType === 'single') {
            $rules['tanggal_kegiatan'] = 'required|date';
            $rules['waktu_mulai'] = 'required';
            $rules['waktu_selesai'] = 'nullable|after:waktu_mulai';
        } else {
            $rules['tanggal_mulai'] = 'required|date';
            $rules['tanggal_selesai'] = 'required|date|after_or_equal:tanggal_mulai';
            $rules['waktu_mulai_multi'] = 'required';
            $rules['waktu_selesai_multi'] = 'nullable|after:waktu_mulai_multi';
        }
        
        $messages = [
            'nama_kegiatan.required' => 'Nama kegiatan wajib diisi.',
            'tanggal_kegiatan.required' => 'Tanggal kegiatan wajib diisi.',
            'waktu_mulai.required' => 'Waktu mulai wajib diisi.',
            'waktu_selesai.after' => 'Waktu selesai harus setelah waktu mulai.',
            'tempat.required' => 'Tempat kegiatan wajib diisi.',
            'jenis_kegiatan.required' => 'Jenis kegiatan wajib dipilih.',
            'target_peserta.min' => 'Target peserta minimal 1 orang.',
            'partisipan.*.exists' => 'Anggota yang dipilih tidak valid.',
        ];

        // Custom validation untuk jenis kegiatan
        if ($request->ref_jenis_kegiatan_id === 'lainnya') {
            if (empty($request->jenis_kegiatan_lainnya)) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['jenis_kegiatan_lainnya' => 'Jenis kegiatan lainnya wajib diisi.']);
            }
        } else {
            // Validasi bahwa ref_jenis_kegiatan_id ada di database
            if (!JenisKegiatan::where('ref_jenis_kegiatan_id', $request->ref_jenis_kegiatan_id)->exists()) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['ref_jenis_kegiatan_id' => 'Jenis kegiatan yang dipilih tidak valid.']);
            }
        }

        $request->validate($rules, $messages);

        try {
            DB::beginTransaction();

            // Prepare data untuk create based on event type
            $kegiatanData = $request->only([
                'nama_kegiatan', 'deskripsi', 'tempat', 'target_peserta', 
                'catatan', 'pic_anggota_id'
            ]);
            
            // Handle date/time fields based on event type
            if ($eventType === 'single') {
                $kegiatanData['tanggal_kegiatan'] = $request->tanggal_kegiatan;
                $kegiatanData['tanggal_mulai'] = $request->tanggal_kegiatan;
                $kegiatanData['tanggal_selesai'] = $request->tanggal_kegiatan;
                $kegiatanData['waktu_mulai'] = $request->waktu_mulai;
                $kegiatanData['waktu_selesai'] = $request->waktu_selesai;
            } else {
                $kegiatanData['tanggal_mulai'] = $request->tanggal_mulai;
                $kegiatanData['tanggal_selesai'] = $request->tanggal_selesai;
                $kegiatanData['tanggal_kegiatan'] = $request->tanggal_mulai; // Set as start date for compatibility
                $kegiatanData['waktu_mulai'] = $request->waktu_mulai_multi;
                $kegiatanData['waktu_selesai'] = $request->waktu_selesai_multi;
            }
            
            // Handle jenis kegiatan
            if ($request->ref_jenis_kegiatan_id === 'lainnya') {
                $kegiatanData['ref_jenis_kegiatan_id'] = null;
                $kegiatanData['jenis_kegiatan_lainnya'] = $request->jenis_kegiatan_lainnya;
            } else {
                $kegiatanData['ref_jenis_kegiatan_id'] = $request->ref_jenis_kegiatan_id;
                $kegiatanData['jenis_kegiatan_lainnya'] = null;
            }

            // Create kegiatan
            $kegiatan = Kegiatan::create($kegiatanData);

            // Add partisipan jika ada
            if ($request->filled('partisipan')) {
                foreach ($request->partisipan as $index => $anggotaId) {
                    $statusPartisipasi = $request->status_partisipasi[$index] ?? 'Wajib';
                    
                    KegiatanPartisipan::create([
                        'kegiatan_id' => $kegiatan->id,
                        'anggota_id' => $anggotaId,
                        'status_partisipasi' => $statusPartisipasi,
                        'status_kehadiran' => 'Belum Konfirmasi'
                    ]);
                }
            }

            DB::commit();
            
            return redirect()->route('kegiatan.show', $kegiatan->id)
                           ->with('success', 'Kegiatan berhasil dibuat!');
                           
        } catch (\Exception $e) {
            DB::rollback();
            
            return redirect()->back()
                           ->withInput()
                           ->with('error', 'Gagal membuat kegiatan: ' . $e->getMessage());
        }
    }

    public function show(Kegiatan $kegiatan)
    {
        $kegiatan->load(['pic', 'partisipan.anggota']);
        
        return view('kegiatan.show', compact('kegiatan'));
    }

    public function edit(Kegiatan $kegiatan)
    {
        if (!$kegiatan->canBeEdited()) {
            return redirect()->route('kegiatan.show', $kegiatan)
                           ->with('error', 'Kegiatan yang sudah selesai tidak dapat diedit!');
        }
        
        $kegiatan->load(['partisipan.anggota']);
        
        // Cache data anggota untuk 5 menit
        $anggotas = cache()->remember('kegiatan_edit_anggotas', 300, function() {
            return Anggota::where('status_keanggotaan', 'Aktif')
                          ->select(['id', 'nama_lengkap', 'jenis_kelamin', 'ref_jenjang_id', 'upa_id', 'dpc_id', 'dpd_id'])
                          ->with([
                              'refJenjang:ref_jenjang_id,jenjang',
                              'upa:upa_id,nama_upa',
                              'dpc:dpc_id,nama_dpc',
                              'dpd:dpd_id,nama_dpd'
                          ])
                          ->orderBy('nama_lengkap')
                          ->get(); // Get all instead of paginate for edit form
        });
        
        // Cache data yang jarang berubah
        $users = cache()->remember('users_list', 300, function() {
            return User::select(['id', 'name'])->orderBy('name')->get();
        });
        
        $jenisKegiatans = cache()->remember('jenis_kegiatan_active', 600, function() {
            return JenisKegiatan::active()->orderBy('nama_jenis_kegiatan')->get();
        });
        
        return view('kegiatan.edit', compact('kegiatan', 'anggotas', 'users', 'jenisKegiatans'));
    }

    public function update(Request $request, Kegiatan $kegiatan)
    {
        if (!$kegiatan->canBeEdited()) {
            return redirect()->route('kegiatan.show', $kegiatan)
                           ->with('error', 'Kegiatan yang sudah selesai tidak dapat diedit!');
        }

        // Determine validation rules based on event type
        $eventType = $request->input('event_type', 'single');
        
        $rules = [
            'nama_kegiatan' => 'required|string|max:255',
            'deskripsi' => 'nullable|string',
            'event_type' => 'required|in:single,multi',
            'tempat' => 'required|string|max:500',
            'ref_jenis_kegiatan_id' => 'required',
            'jenis_kegiatan_lainnya' => 'required_if:ref_jenis_kegiatan_id,lainnya|nullable|string|max:255',
            'status_kegiatan' => 'required|in:Direncanakan,Berlangsung,Selesai,Dibatalkan',
            'target_peserta' => 'nullable|integer|min:1',
            'catatan' => 'nullable|string',
            'pic_anggota_id' => 'nullable|exists:tbl_anggota,id',
            'partisipan' => 'nullable|array',
            'partisipan.*' => 'exists:tbl_anggota,id',
            'status_partisipasi' => 'nullable|array',
            'status_partisipasi.*' => 'in:Wajib,Opsional,Undangan',
        ];
        
        // Add conditional validation rules based on event type
        if ($eventType === 'single') {
            $rules['tanggal_kegiatan'] = 'required|date';
            $rules['waktu_mulai'] = 'required';
            $rules['waktu_selesai'] = 'nullable|after:waktu_mulai';
        } else {
            $rules['tanggal_mulai'] = 'required|date';
            $rules['tanggal_selesai'] = 'required|date|after_or_equal:tanggal_mulai';
            $rules['waktu_mulai_multi'] = 'required';
            $rules['waktu_selesai_multi'] = 'nullable|after:waktu_mulai_multi';
        }

        // Custom validation untuk jenis kegiatan
        if ($request->ref_jenis_kegiatan_id === 'lainnya') {
            if (empty($request->jenis_kegiatan_lainnya)) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['jenis_kegiatan_lainnya' => 'Jenis kegiatan lainnya wajib diisi.']);
            }
        } else {
            // Validasi bahwa ref_jenis_kegiatan_id ada di database
            if (!JenisKegiatan::where('ref_jenis_kegiatan_id', $request->ref_jenis_kegiatan_id)->exists()) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['ref_jenis_kegiatan_id' => 'Jenis kegiatan yang dipilih tidak valid.']);
            }
        }

        $request->validate($rules);

        try {
            DB::beginTransaction();

            // Prepare data untuk update based on event type
            $kegiatanData = $request->only([
                'nama_kegiatan', 'deskripsi', 'tempat', 'status_kegiatan',
                'target_peserta', 'catatan', 'pic_anggota_id'
            ]);
            
            // Handle date/time fields based on event type
            if ($eventType === 'single') {
                $kegiatanData['tanggal_kegiatan'] = $request->tanggal_kegiatan;
                $kegiatanData['tanggal_mulai'] = $request->tanggal_kegiatan;
                $kegiatanData['tanggal_selesai'] = $request->tanggal_kegiatan;
                $kegiatanData['waktu_mulai'] = $request->waktu_mulai;
                $kegiatanData['waktu_selesai'] = $request->waktu_selesai;
            } else {
                $kegiatanData['tanggal_mulai'] = $request->tanggal_mulai;
                $kegiatanData['tanggal_selesai'] = $request->tanggal_selesai;
                $kegiatanData['tanggal_kegiatan'] = $request->tanggal_mulai; // Set as start date for compatibility
                $kegiatanData['waktu_mulai'] = $request->waktu_mulai_multi;
                $kegiatanData['waktu_selesai'] = $request->waktu_selesai_multi;
            }
            
            // Handle jenis kegiatan
            if ($request->ref_jenis_kegiatan_id === 'lainnya') {
                $kegiatanData['ref_jenis_kegiatan_id'] = null;
                $kegiatanData['jenis_kegiatan_lainnya'] = $request->jenis_kegiatan_lainnya;
            } else {
                $kegiatanData['ref_jenis_kegiatan_id'] = $request->ref_jenis_kegiatan_id;
                $kegiatanData['jenis_kegiatan_lainnya'] = null;
            }

            // Update kegiatan
            $kegiatan->update($kegiatanData);

            // Update partisipan
            if ($request->filled('partisipan')) {
                // Hapus partisipan lama
                $kegiatan->partisipan()->delete();
                
                // Tambah partisipan baru
                foreach ($request->partisipan as $index => $anggotaId) {
                    $statusPartisipasi = $request->status_partisipasi[$index] ?? 'Wajib';
                    
                    KegiatanPartisipan::create([
                        'kegiatan_id' => $kegiatan->id,
                        'anggota_id' => $anggotaId,
                        'status_partisipasi' => $statusPartisipasi,
                        'status_kehadiran' => 'Belum Konfirmasi'
                    ]);
                }
            } else {
                // Jika tidak ada partisipan yang dipilih, hapus semua
                $kegiatan->partisipan()->delete();
            }

            DB::commit();
            
            return redirect()->route('kegiatan.show', $kegiatan)
                           ->with('success', 'Kegiatan berhasil diupdate!');
                           
        } catch (\Exception $e) {
            DB::rollback();
            
            return redirect()->back()
                           ->withInput()
                           ->with('error', 'Gagal update kegiatan: ' . $e->getMessage());
        }
    }

    public function destroy(Kegiatan $kegiatan)
    {
        if (!$kegiatan->canBeEdited()) {
            return redirect()->route('kegiatan.index')
                           ->with('error', 'Kegiatan yang sudah selesai tidak dapat dihapus!');
        }

        try {
            DB::beginTransaction();
            
            // Hapus partisipan dulu (karena foreign key)
            $kegiatan->partisipan()->delete();
            
            // Hapus kegiatan
            $kegiatan->delete();
            
            DB::commit();
            
            return redirect()->route('kegiatan.index')
                           ->with('success', 'Kegiatan berhasil dihapus!');
                           
        } catch (\Exception $e) {
            DB::rollback();
            
            return redirect()->route('kegiatan.index')
                           ->with('error', 'Gagal menghapus kegiatan: ' . $e->getMessage());
        }
    }

    public function updateKehadiran(Request $request, $id)
    {
        $partisipan = KegiatanPartisipan::findOrFail($id);
        
        $request->validate([
            'status_kehadiran' => 'required|in:Belum Konfirmasi,Hadir,Tidak Hadir,Izin',
            'keterangan' => 'nullable|string|max:255'
        ]);

        $partisipan->update([
            'status_kehadiran' => $request->status_kehadiran,
            'keterangan' => $request->keterangan,
            'waktu_konfirmasi' => now()
        ]);

        return redirect()->back()
                       ->with('success', 'Status kehadiran berhasil diupdate!');
    }
}