<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\StudentModel;
use App\Models\ClassroomModel;
use App\Models\GradeModel;
use App\Models\AcademicPeriodModel;
use App\Models\StudentCardSettingModel;
use App\Models\SchoolSettingModel;
use App\Models\StudentAcademicHistoryModel;
use App\Services\StorageService;
use ZipArchive;

class StudentCard extends BaseController
{
    protected $studentModel;
    protected $classroomModel;
    protected $gradeModel;
    protected $periodModel;
    protected $historyModel;
    protected $cardSettingModel;
    protected $schoolSettingModel;

    public function __construct()
    {
        $this->studentModel = new StudentModel();
        $this->classroomModel = new ClassroomModel();
        $this->gradeModel = new GradeModel();
        $this->periodModel = new AcademicPeriodModel();
        $this->historyModel = new StudentAcademicHistoryModel();
        $this->cardSettingModel = new StudentCardSettingModel();
        $this->schoolSettingModel = new SchoolSettingModel();
    }

    private function checkLogin()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }
        $role = session()->get('user_role');
        if (!in_array($role, ['superadmin', 'admin'])) {
            return redirect()->to('/dashboard')->with('error', 'Akses ditolak!');
        }
        return null;
    }

    public function index()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activePeriod = $this->periodModel->getActive();
        
        $data = [
            'title'         => 'Kartu Pelajar',
            'activePeriod'  => $activePeriod,
            'grades'        => $this->gradeModel->orderBy('order', 'ASC')->findAll(),
            'classrooms'    => $this->classroomModel->getAllWithRelations(),
        ];

        return view('student_card/index', $data);
    }

    // AJAX: Ambil siswa berdasarkan kelas
    public function getStudents()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $classroomId = $this->request->getGet('classroom_id');
        $periodId = $this->request->getGet('period_id');

        if (!$classroomId || !$periodId) {
            return $this->response->setJSON([]);
        }

        $db = \Config\Database::connect();
        $students = $db->table('student_academic_histories as sah')
            ->select('students.id, students.nis, students.nisn, students.full_name, students.photo, students.gender, students.birth_place, students.birth_date, students.religion, students.address, students.village, students.district, students.city, students.father_name, students.mother_name, classrooms.name as classroom_name, classrooms.id as classroom_id, grades.name as grade_name')
            ->join('students', 'students.id = sah.student_id')
            ->join('classrooms', 'classrooms.id = sah.classroom_id')
            ->join('grades', 'grades.id = classrooms.grade_id')
            ->where('sah.classroom_id', $classroomId)
            ->where('sah.academic_period_id', $periodId)
            ->where('students.deleted_at', null)
            ->where('students.status', 'Aktif')
            ->orderBy('students.full_name', 'ASC')
            ->get()
            ->getResultArray();

        foreach ($students as &$s) {
            $s['photo_url'] = StorageService::getUrl($s['photo'], 'students');
        }

        return $this->response->setJSON($students);
    }

    // Halaman cetak kartu
public function print()
{
    if ($redirect = $this->checkLogin()) return $redirect;

    $studentIds = $this->request->getGet('student_ids');
    
    if (empty($studentIds)) {
        return redirect()->back()->with('error', 'Pilih siswa terlebih dahulu!');
    }
    
    $studentIds = explode(',', $studentIds);
    
    // Ambil data siswa
    $students = $this->studentModel->whereIn('id', $studentIds)->findAll();
    
    // Ambil data kelas untuk setiap siswa
    $activePeriod = $this->periodModel->getActive();
    if ($activePeriod) {
        foreach ($students as &$student) {
            $history = $this->historyModel
                ->where('student_id', $student['id'])
                ->where('academic_period_id', $activePeriod['id'])
                ->first();
            $classroom = $this->classroomModel->find($history['classroom_id'] ?? 0);
            $grade = $this->gradeModel->find($classroom['grade_id'] ?? 0);
            $student['classroom_name'] = $classroom['name'] ?? '-';
            $student['grade_name'] = $grade['name'] ?? '-';
        }
    }

    // Urutkan berdasarkan kelas, lalu nama
    usort($students, function ($a, $b) {
        $classCmp = strcmp($a['classroom_name'] ?? '', $b['classroom_name'] ?? '');
        if ($classCmp !== 0) {
            return $classCmp;
        }
        return strcmp($a['full_name'] ?? '', $b['full_name'] ?? '');
    });
    
    // ========== LOAD HELPER DULU ==========
    helper('card');
    // ======================================
    
    // Ambil setting
    $settings = getCardSettings();
    $cardSettings = $this->cardSettingModel->getSettings();
    
    // Ambil data sekolah
    $schoolData = $this->schoolSettingModel->getSettings();
    
    $data = [
        'title'     => 'Cetak Kartu Pelajar',
        'students'  => $students,
        'settings'  => array_merge($settings, $cardSettings ?? [], $schoolData ?? []),
        'print_date'=> date('d F Y'),
        'district'  => $settings['district'] ?? $schoolData['district'] ?? 'Wonogiri',
    ];
    
    return view('student_card/print', $data);
}

    // Halaman setting kartu
    public function settings()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $data = [
            'title'    => 'Setting Kartu Pelajar',
            'settings' => $this->cardSettingModel->getSettings(),
        ];

        return view('student_card/settings', $data);
    }

    // Save setting kartu
    public function saveSettings()
    {
        if ($redirect = $this->checkLogin()) return $redirect;
 
        $frontBg   = $this->uploadFile('front_background',     $this->request->getPost('old_front_background'));
        $backBg    = $this->uploadFile('back_background',      $this->request->getPost('old_back_background'));
        $stamp     = $this->uploadFile('school_stamp',         $this->request->getPost('old_school_stamp'));
        $signature = $this->uploadFile('headmaster_signature', $this->request->getPost('old_headmaster_signature'));
 
        $data = [
            'front_background'     => $frontBg,
            'back_background'      => $backBg,
            'school_stamp'         => $stamp,
            'headmaster_signature' => $signature,
            'card_validity'        => $this->request->getPost('card_validity'),
            'show_qrcode'          => $this->request->getPost('show_qrcode') ? 1 : 0,
            'card_date'            => $this->request->getPost('card_date') ?: null,
            'motto'                => $this->request->getPost('motto'),
        ];
 
        $existing = $this->cardSettingModel->first();
        if ($existing) {
            $this->cardSettingModel->update($existing['id'], $data);
        } else {
            $this->cardSettingModel->insert($data);
        }
 
        return redirect()->to('/student-card/settings')
            ->with('success', 'Setting kartu berhasil disimpan!');
    }

    private function uploadFile($fieldName, $oldFile = null)
    {
        $file = $this->request->getFile($fieldName);
        
        if (!$file || !$file->isValid() || $file->hasMoved()) {
            return $oldFile;
        }

        // Validasi file gambar
        if (!in_array($file->getMimeType(), ['image/jpeg', 'image/png', 'image/jpg', 'image/gif'])) {
            session()->setFlashdata('error', 'Format file harus JPG, PNG, atau GIF');
            return $oldFile;
        }

        // Validasi ukuran (max 2MB)
        if ($file->getSize() > 2 * 1024 * 1024) {
            session()->setFlashdata('error', 'Ukuran file maksimal 2MB');
            return $oldFile;
        }

        // Hapus file lama
        if ($oldFile && file_exists(FCPATH . 'uploads/card/' . $oldFile)) {
            unlink(FCPATH . 'uploads/card/' . $oldFile);
        }

        // Buat folder jika belum ada
        $uploadPath = FCPATH . 'uploads/card';
        if (!is_dir($uploadPath)) {
            mkdir($uploadPath, 0777, true);
        }

        // Generate nama baru
        $newName = $fieldName . '_' . time() . '.' . $file->getExtension();
        $file->move($uploadPath, $newName);

        return $newName;
    }

    // Upload foto siswa per baris (AJAX)
    public function uploadPhoto()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $studentId = $this->request->getPost('student_id');
        $file = $this->request->getFile('photo');

        if (!$studentId || !$file || !$file->isValid()) {
            return $this->response->setJSON(['success' => false, 'message' => 'Gagal upload']);
        }

        // Validasi
        if (!in_array($file->getMimeType(), ['image/jpeg', 'image/png', 'image/jpg'])) {
            return $this->response->setJSON(['success' => false, 'message' => 'Format harus JPG/PNG']);
        }

        if ($file->getSize() > 1 * 1024 * 1024) {
            return $this->response->setJSON(['success' => false, 'message' => 'Ukuran maksimal 1MB']);
        }

        // Kompresi berkas temporer sebelum di-upload
        $this->compressAndResizePhoto($file->getTempName());

        // Hapus foto lama
        $student = $this->studentModel->find($studentId);
        if ($student && !empty($student['photo'])) {
            StorageService::delete($student['photo'], 'students');
        }

        // Upload menggunakan StorageService
        $uploadedPhoto = StorageService::upload($file, 'students');
        if ($uploadedPhoto) {
            $this->studentModel->update($studentId, ['photo' => $uploadedPhoto]);
            return $this->response->setJSON(['success' => true, 'message' => 'Foto berhasil diupload', 'photo' => $uploadedPhoto]);
        }

        return $this->response->setJSON(['success' => false, 'message' => 'Gagal mengunggah foto ke penyimpanan']);
    }

    // Upload massal foto via ZIP
    public function uploadMassPhoto()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $file = $this->request->getFile('zip_file');

        if (!$file || !$file->isValid()) {
            return redirect()->back()->with('error', 'File tidak valid!');
        }

        if ($file->getExtension() != 'zip') {
            return redirect()->back()->with('error', 'File harus berformat ZIP!');
        }

        $zipPath = FCPATH . 'uploads/temp/' . $file->getName();
        $extractPath = FCPATH . 'uploads/temp/extract_' . time();

        // Buat folder temp
        if (!is_dir(FCPATH . 'uploads/temp')) {
            mkdir(FCPATH . 'uploads/temp', 0777, true);
        }

        // Upload file zip
        $file->move(FCPATH . 'uploads/temp', $file->getName());

        // Extract zip
        $zip = new ZipArchive();
        if ($zip->open($zipPath) === true) {
            $zip->extractTo($extractPath);
            $zip->close();
        } else {
            return redirect()->back()->with('error', 'Gagal mengekstrak file ZIP');
        }

        // Proses setiap file foto
        $success = 0;
        $failed = 0;
        $errors = [];

        $files = scandir($extractPath);
        foreach ($files as $filename) {
            if ($filename == '.' || $filename == '..') continue;
            
            $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
            if (!in_array($extension, ['jpg', 'jpeg', 'png'])) continue;
            
            // Ambil identifier (NISN/NIS) dari nama file (tanpa ekstensi)
            $identifier = pathinfo($filename, PATHINFO_FILENAME);
            
            // Cari siswa dengan NISN atau NIS tersebut
            $student = $this->studentModel
                ->groupStart()
                    ->where('nisn', $identifier)
                    ->orWhere('nis', $identifier)
                ->groupEnd()
                ->first();
            
            if ($student) {
                // Hapus foto lama jika ada
                if (!empty($student['photo'])) {
                    StorageService::delete($student['photo'], 'students');
                }
                
                // Pindahkan file ke folder students
                $newName = 'student_' . $student['id'] . '_' . time() . '.' . $extension;
                $sourcePath = $extractPath . '/' . $filename;
                
                // Kompresi berkas temporer terlebih dahulu
                $this->compressAndResizePhoto($sourcePath);
                
                // Upload via StorageService
                $uploadedPhoto = StorageService::uploadFromPath($sourcePath, $newName, mime_content_type($sourcePath), 'students');
                if ($uploadedPhoto) {
                    $this->studentModel->update($student['id'], ['photo' => $uploadedPhoto]);
                    $success++;
                } else {
                    $failed++;
                    $errors[] = $filename . ' (gagal copy ke penyimpanan)';
                }
            } else {
                $failed++;
                $errors[] = $filename . ' (NISN/NIS tidak ditemukan)';
            }
        }

        // Bersihkan file temporary
        @unlink($zipPath);
        $this->deleteDirectory($extractPath);

        $message = "Berhasil upload {$success} foto. Gagal: {$failed}.";
        if (!empty($errors)) {
            session()->setFlashdata('import_errors', $errors);
        }

        return redirect()->to('/student-card')->with('success', $message);
    }

    private function deleteDirectory($dir)
    {
        if (!is_dir($dir)) return;
        $files = array_diff(scandir($dir), ['.', '..']);
        foreach ($files as $file) {
            is_dir("$dir/$file") ? $this->deleteDirectory("$dir/$file") : unlink("$dir/$file");
        }
        rmdir($dir);
    }

    // Hapus foto siswa
    public function deletePhoto($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $student = $this->studentModel->find($id);
        if (!$student) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Siswa tidak ditemukan!'
            ]);
        }

        $photo = $student['photo'];
        
        if (!empty($photo)) {
            StorageService::delete($photo, 'students');
            $this->studentModel->update($id, ['photo' => null]);
            
            return $this->response->setJSON([
                'success' => true,
                'message' => 'Foto berhasil dihapus!'
            ]);
        }
        
        return $this->response->setJSON([
            'success' => false,
            'message' => 'Siswa tidak memiliki foto!'
        ]);
    }

    private function compressAndResizePhoto($filePath)
    {
        try {
            $image = \Config\Services::image()->withFile($filePath);
            
            $width = $image->getWidth();
            if ($width > 400) {
                $image->resize(400, 533, true, 'width');
            }
            
            $image->save($filePath, 80);
            return true;
        } catch (\Exception $e) {
            log_message('error', 'Image compression failed: ' . $e->getMessage());
            return false;
        }
    }

}