<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Anggota;
use App\Models\Upa;
use App\Models\Dpc;
use App\Models\RefJenjang;
use App\Models\RiwayatPerpindahanAnggota;
use Illuminate\Support\Facades\DB;
use PDF;

class SuratPenempatanController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $query = Anggota::with(['refJenjang', 'dpc', 'upa', 'refGrupUpa'])
            ->where('status_keanggotaan', 'Aktif');

        // Filter by DPC
        if ($request->filled('dpc_id')) {
            $query->where('dpc_id', $request->dpc_id);
        }

        // Filter by UPA
        if ($request->filled('upa_id')) {
            $query->where('upa_id', $request->upa_id);
        }

        // Filter by Jenjang
        if ($request->filled('jenjang_id')) {
            $query->where('ref_jenjang_id', $request->jenjang_id);
        }

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

        $anggotas = $query->orderBy('nama_lengkap')->paginate(15);

        $dpcList = Dpc::where('is_active', true)->get();
        $upaList = Upa::where('status', 'Aktif')->get();
        $jenjangList = RefJenjang::all();

        return view('surat-penempatan.index', compact('anggotas', 'dpcList', 'upaList', 'jenjangList'));
    }

    /**
     * Show the form for creating a new surat penempatan.
     */
    public function create()
    {
        $anggotas = Anggota::with(['refJenjang', 'dpc', 'upa', 'refGrupUpa'])
            ->where('status_keanggotaan', 'Aktif')
            ->orderBy('nama_lengkap')
            ->get();

        $upaList = Upa::with(['dpc', 'pembimbingAktif'])
            ->where('status', 'Aktif')
            ->whereNotNull('dpc_id')
            ->get();

        $dpcList = Dpc::where('is_active', true)->get();

        return view('surat-penempatan.create', compact('anggotas', 'upaList', 'dpcList'));
    }

    /**
     * Generate surat penempatan for selected anggota
     */
    public function generate(Request $request)
    {
        $request->validate([
            'anggota_id' => 'required|exists:tbl_anggota,id',
            'upa_id' => 'required|exists:tbl_upa,upa_id',
            'pembimbing_baru_id' => 'required|exists:tbl_anggota,id',
            'pembimbing_lama_id' => 'nullable|exists:tbl_anggota,id',
            'tahun_pelantikan' => 'required|date',
            'catatan' => 'nullable|string|max:500'
        ]);

        $anggota = Anggota::with(['refJenjang', 'dpc', 'upa', 'refGrupUpa'])->findOrFail($request->anggota_id);
        $upa = Upa::with(['dpc', 'pembimbingAktif'])->findOrFail($request->upa_id);
        $pembimbingBaru = Anggota::findOrFail($request->pembimbing_baru_id);
        $pembimbingLama = $request->pembimbing_lama_id ? Anggota::findOrFail($request->pembimbing_lama_id) : null;

        // Generate nomor surat
        $nomorSurat = $this->generateNomorSurat();

        $data = [
            'nomor_surat' => $nomorSurat,
            'tanggal' => now()->format('d-m-Y'),
            'anggota' => $anggota,
            'upa' => $upa,
            'pembimbing_baru' => $pembimbingBaru,
            'pembimbing_lama' => $pembimbingLama,
            'tahun_pelantikan' => $request->tahun_pelantikan,
            'catatan' => $request->catatan,
            'ketua_kaderisasi' => 'H. Indarmawan, Ak'
        ];

        return view('surat.penempatan-upa', $data);
    }

    /**
     * Generate PDF surat penempatan
     */
    public function generatePDF(Request $request)
    {
        $request->validate([
            'anggota_id' => 'required|exists:tbl_anggota,id',
            'upa_id' => 'required|exists:tbl_upa,upa_id',
            'pembimbing_baru_id' => 'required|exists:tbl_anggota,id',
            'pembimbing_lama_id' => 'nullable|exists:tbl_anggota,id',
            'tahun_pelantikan' => 'required|date',
            'catatan' => 'nullable|string|max:500'
        ]);

        $anggota = Anggota::with(['refJenjang', 'dpc', 'upa', 'refGrupUpa'])->findOrFail($request->anggota_id);
        $upa = Upa::with(['dpc', 'pembimbingAktif'])->findOrFail($request->upa_id);
        $pembimbingBaru = Anggota::findOrFail($request->pembimbing_baru_id);
        $pembimbingLama = $request->pembimbing_lama_id ? Anggota::findOrFail($request->pembimbing_lama_id) : null;

        // Generate nomor surat
        $nomorSurat = $this->generateNomorSurat();

        $data = [
            'nomor_surat' => $nomorSurat,
            'tanggal' => now()->format('d-m-Y'),
            'anggota' => $anggota,
            'upa' => $upa,
            'pembimbing_baru' => $pembimbingBaru,
            'pembimbing_lama' => $pembimbingLama,
            'tahun_pelantikan' => $request->tahun_pelantikan,
            'catatan' => $request->catatan,
            'ketua_kaderisasi' => 'H. Indarmawan, Ak'
        ];

        $pdf = PDF::loadView('surat.penempatan-upa', $data);
        $pdf->setPaper('A4', 'portrait');
        $pdf->setOptions([
            'isHtml5ParserEnabled' => true,
            'isRemoteEnabled' => false,
            'isPhpEnabled' => false,
            'isJavascriptEnabled' => false,
            'defaultFont' => 'Arial',
            'dpi' => 150,
        ]);

        $filename = "Surat_Penempatan_UPA_{$anggota->nama_lengkap}.pdf";
        return $pdf->download($filename);
    }

    /**
     * Show detail surat penempatan
     */
    public function show($id)
    {
        $riwayat = RiwayatPerpindahanAnggota::with([
            'anggota', 'upaAsal', 'upaTujuan', 'dpcAsal', 'dpcTujuan', 
            'pembimbingLama', 'pembimbingBaru', 'creator', 'approver'
        ])->findOrFail($id);

        return view('surat-penempatan.show', compact('riwayat'));
    }

    /**
     * Print surat penempatan
     */
    public function print($id)
    {
        $riwayat = RiwayatPerpindahanAnggota::with([
            'anggota', 'upaAsal', 'upaTujuan', 'dpcAsal', 'dpcTujuan', 
            'pembimbingLama', 'pembimbingBaru'
        ])->findOrFail($id);

        $data = [
            'nomor_surat' => $riwayat->nomor_surat,
            'tanggal' => $riwayat->tanggal_efektif ? $riwayat->tanggal_efektif->format('d-m-Y') : now()->format('d-m-Y'),
            'anggota' => $riwayat->anggota,
            'upa' => $riwayat->upaTujuan,
            'pembimbing_baru' => $riwayat->pembimbingBaru,
            'pembimbing_lama' => $riwayat->pembimbingLama,
            'tahun_pelantikan' => $riwayat->tahun_pelantikan,
            'catatan' => $riwayat->catatan,
            'ketua_kaderisasi' => 'H. Indarmawan, Ak'
        ];

        $pdf = PDF::loadView('surat.penempatan-upa', $data);
        $pdf->setPaper('A4', 'portrait');
        $pdf->setOptions([
            'isHtml5ParserEnabled' => true,
            'isRemoteEnabled' => false,
            'isPhpEnabled' => false,
            'isJavascriptEnabled' => false,
            'defaultFont' => 'Arial',
            'dpi' => 150,
        ]);

        $filename = "Surat_Penempatan_UPA_{$riwayat->anggota->nama_lengkap}.pdf";
        return $pdf->download($filename);
    }

    /**
     * Transfer anggota dan update database
     */
    public function transferAnggota(Request $request)
    {
        $request->validate([
            'anggota_id' => 'required|exists:tbl_anggota,id',
            'dpc_asal_id' => 'required|exists:tbl_dpc,dpc_id',
            'upa_asal_id' => 'required|exists:tbl_upa,upa_id',
            'dpc_tujuan_id' => 'required|exists:tbl_dpc,dpc_id',
            'upa_tujuan_id' => 'required|exists:tbl_upa,upa_id',
            'pembimbing_baru_id' => 'required|exists:tbl_anggota,id',
            'pembimbing_lama_id' => 'nullable|exists:tbl_anggota,id',
            'tahun_pelantikan' => 'required|date',
            'catatan' => 'nullable|string|max:500'
        ]);

        try {
            DB::beginTransaction();

            // Ambil data anggota dan UPA
            $anggota = Anggota::with(['refJenjang', 'dpc', 'upa', 'refGrupUpa'])->findOrFail($request->anggota_id);
            $upaTujuan = Upa::with(['dpc'])->findOrFail($request->upa_tujuan_id);
            $pembimbingBaru = Anggota::findOrFail($request->pembimbing_baru_id);
            $pembimbingLama = $request->pembimbing_lama_id ? Anggota::findOrFail($request->pembimbing_lama_id) : null;

            // Simpan data lama ke history sebelum update
            $anggota->saveToHistory('Transfer melalui Surat Penempatan UPA');

            // Update data anggota
            $anggota->update([
                'dpc_id' => $request->dpc_tujuan_id,
                'upa_id' => $request->upa_tujuan_id,
                'dpd_id' => $upaTujuan->dpc->dpd_id ?? $anggota->dpd_id, // Update DPD jika ada
            ]);

            // Generate nomor surat dengan retry mechanism
            $nomorSurat = $this->generateNomorSurat();
            $retryCount = 0;
            $maxRetries = 3;
            
            while (DB::table('tbl_riwayat_perpindahan_anggota')->where('nomor_surat', $nomorSurat)->exists() && $retryCount < $maxRetries) {
                $nomorSurat = $this->generateNomorSurat();
                $retryCount++;
            }
            
            // Jika masih duplicate setelah retry, gunakan timestamp
            if (DB::table('tbl_riwayat_perpindahan_anggota')->where('nomor_surat', $nomorSurat)->exists()) {
                $nomorSurat = $this->generateNomorSuratWithTimestamp();
            }
            
            // Jika masih duplicate, gunakan database sequence
            if (DB::table('tbl_riwayat_perpindahan_anggota')->where('nomor_surat', $nomorSurat)->exists()) {
                $nomorSurat = $this->generateNomorSuratWithSequence();
            }
            
            // Jika masih duplicate, gunakan UUID sebagai fallback terakhir
            if (DB::table('tbl_riwayat_perpindahan_anggota')->where('nomor_surat', $nomorSurat)->exists()) {
                $nomorSurat = $this->generateNomorSuratWithUUID();
            }

            // Simpan riwayat perpindahan
            $riwayat = RiwayatPerpindahanAnggota::create([
                'tipe_transaksi' => 'penempatan',
                'anggota_id' => $anggota->id,
                'upa_asal_id' => $request->upa_asal_id,
                'upa_tujuan_id' => $request->upa_tujuan_id,
                'dpc_asal_id' => $request->dpc_asal_id,
                'dpc_tujuan_id' => $request->dpc_tujuan_id,
                'pembimbing_lama_id' => $pembimbingLama?->id,
                'pembimbing_baru_id' => $pembimbingBaru->id,
                'tanggal_efektif' => now()->toDateString(),
                'tahun_pelantikan' => $request->tahun_pelantikan,
                'nomor_surat' => $nomorSurat,
                'alasan' => 'Penempatan melalui Surat Penempatan UPA',
                'catatan' => $request->catatan,
                'status' => 'completed',
                'created_by' => auth()->id(),
                'approved_by' => auth()->id(),
                'approved_at' => now(),
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Anggota berhasil dipindahkan dan database telah diupdate.',
                'data' => [
                    'anggota' => $anggota->fresh(['dpc', 'upa', 'refJenjang']),
                    'nomor_surat' => $nomorSurat,
                    'tanggal_transfer' => now()->format('d-m-Y H:i:s'),
                    'redirect_url' => route('surat-penempatan.show', $riwayat->id)
                ]
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            
            // Handle specific database errors
            if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
                return response()->json([
                    'success' => false,
                    'message' => 'Nomor surat sudah pernah digunakan. Silakan coba lagi.'
                ], 400);
            }
            
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan saat memindahkan anggota: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get anggota by DPC for AJAX
     */
    public function getAnggotaByDpc(Request $request)
    {
        $dpcId = $request->dpc_id;
        
        $anggotas = Anggota::where('dpc_id', $dpcId)
            ->where('status_keanggotaan', 'Aktif')
            ->select('id', 'nama_lengkap', 'nomor_identitas_anggota')
            ->get();

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

    /**
     * Get UPA by DPC for AJAX
     */
    public function getUpaByDpc(Request $request)
    {
        $dpcId = $request->dpc_id;
        
        $upas = Upa::where('dpc_id', $dpcId)
            ->where('status', 'Aktif')
            ->select('upa_id', 'kode_upa', 'nama_upa')
            ->get();

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

    /**
     * Get pembimbing by UPA for AJAX
     */
    public function getPembimbingByUpa(Request $request)
    {
        $upaId = $request->upa_id;
        
        $pembimbing = Anggota::whereHas('upaPembimbing', function($query) use ($upaId) {
            $query->where('tbl_upa_pembimbing.upa_id', $upaId)
                  ->where('tbl_upa_pembimbing.status', 'Aktif');
        })
        ->with(['upaPembimbing' => function($query) use ($upaId) {
            $query->where('tbl_upa_pembimbing.upa_id', $upaId)
                  ->where('tbl_upa_pembimbing.status', 'Aktif')
                  ->select('tbl_upa.upa_id', 'tbl_upa_pembimbing.anggota_id', 'tbl_upa_pembimbing.jabatan');
        }])
        ->select('id', 'nama_lengkap', 'nomor_identitas_anggota', 'no_telepon')
        ->get()
        ->map(function($anggota) {
            // Ambil jabatan dari relasi pivot
            $jabatan = $anggota->upaPembimbing->first()->pivot->jabatan ?? 'Pembimbing';
            return [
                'id' => $anggota->id,
                'nama_lengkap' => $anggota->nama_lengkap,
                'nomor_identitas_anggota' => $anggota->nomor_identitas_anggota,
                'no_telepon' => $anggota->no_telepon,
                'jabatan' => $jabatan
            ];
        });

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

    /**
     * Generate nomor surat
     */
    private function generateNomorSurat()
    {
        $bulan = now()->format('m');
        $tahun = now()->format('Y');
        $bulanRomawi = $this->convertToRoman($bulan);
        
        // Get next sequence number for this month from riwayat perpindahan
        $lastSurat = DB::table('tbl_riwayat_perpindahan_anggota')
            ->where('created_at', '>=', now()->startOfMonth())
            ->where('nomor_surat', 'like', "%/D/Mts/A1-04-PKS/{$bulanRomawi}/{$tahun}")
            ->count();
        
        $sequence = str_pad($lastSurat + 1, 3, '0', STR_PAD_LEFT);
        $nomorSurat = "{$sequence}/D/Mts/A1-04-PKS/{$bulanRomawi}/{$tahun}";
        
        return $nomorSurat;
    }

    /**
     * Generate nomor surat dengan timestamp untuk memastikan unik
     */
    private function generateNomorSuratWithTimestamp()
    {
        $bulan = now()->format('m');
        $tahun = now()->format('Y');
        $bulanRomawi = $this->convertToRoman($bulan);
        
        // Generate sequence dengan timestamp untuk memastikan unik
        $timestamp = now()->format('His'); // HHMMSS
        $sequence = str_pad($timestamp, 6, '0', STR_PAD_LEFT);
        
        return "{$sequence}/D/Mts/A1-04-PKS/{$bulanRomawi}/{$tahun}";
    }

    /**
     * Generate nomor surat dengan UUID untuk memastikan unik
     */
    private function generateNomorSuratWithUUID()
    {
        $bulan = now()->format('m');
        $tahun = now()->format('Y');
        $bulanRomawi = $this->convertToRoman($bulan);
        
        // Generate sequence dengan UUID untuk memastikan unik
        $uuid = substr(str_replace('-', '', \Illuminate\Support\Str::uuid()->toString()), 0, 6);
        
        return "{$uuid}/D/Mts/A1-04-PKS/{$bulanRomawi}/{$tahun}";
    }

    /**
     * Generate nomor surat dengan database sequence untuk memastikan unik
     */
    private function generateNomorSuratWithSequence()
    {
        $bulan = now()->format('m');
        $tahun = now()->format('Y');
        $bulanRomawi = $this->convertToRoman($bulan);
        
        // Get max sequence number for this month
        $maxSequence = DB::table('tbl_riwayat_perpindahan_anggota')
            ->where('created_at', '>=', now()->startOfMonth())
            ->where('nomor_surat', 'like', "%/D/Mts/A1-04-PKS/{$bulanRomawi}/{$tahun}")
            ->max(DB::raw('CAST(SUBSTRING(nomor_surat, 1, LOCATE("/", nomor_surat) - 1) AS UNSIGNED)'));
        
        $sequence = str_pad(($maxSequence ?? 0) + 1, 3, '0', STR_PAD_LEFT);
        
        return "{$sequence}/D/Mts/A1-04-PKS/{$bulanRomawi}/{$tahun}";
    }

    /**
     * Convert number to Roman numeral
     */
    private function convertToRoman($number)
    {
        $romans = [
            'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII'
        ];
        
        return $romans[$number - 1] ?? 'I';
    }
}
