<?php

namespace App\Controllers;

use App\Models\OpdModel;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\IOFactory;

class Pegawai extends BaseController
{
    public function index()
    {
        $level = session()->get('level');
        $id_opd_session = session()->get('id_opd');
        $opdModel = new OpdModel();

        $data = [
            'title'    => 'Manajemen Pegawai',
            'level'    => $level,
            'opd_list' => ($level == 'admin')
                ? $opdModel->orderBy('nama_opd', 'ASC')->findAll()
                : $opdModel->where('id_opd', $id_opd_session)->findAll()
        ];

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

    public function get_lokasi_by_opd($id_opd = null)
    {
        $db = \Config\Database::connect();
        if (!$id_opd || $id_opd == "null") return $this->response->setJSON([]);
        $data = $db->table('opd_lokasi')->where('id_opd', $id_opd)->get()->getResultArray();
        return $this->response->setJSON($data);
    }

    public function update_lokasi()
    {
        $db = \Config\Database::connect();
        $id_pegawai = $this->request->getPost('id_pegawai');
        $id_lokasi_array = $this->request->getPost('id_lokasi');

        $lokasi_string = (!empty($id_lokasi_array)) ? implode(',', $id_lokasi_array) : null;

        $db->table('pegawai')->where('id_pegawai', $id_pegawai)->update(['id_lokasi' => $lokasi_string]);
        return $this->response->setJSON(['status' => 'success', 'message' => 'Multi-Lokasi berhasil diperbarui!']);
    }

    // --- [BARU] FUNGSI TRANSFER PEGAWAI KE OPD LAIN ---
    public function transfer_opd()
    {
        $db = \Config\Database::connect();
        $id_pegawai = $this->request->getPost('id_pegawai');
        $id_opd_baru = $this->request->getPost('id_opd_tujuan');

        if (!$id_pegawai || !$id_opd_baru) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Data tidak lengkap.']);
        }

        // Update ID OPD dan RESET lokasi (karena lokasi lama pasti tidak valid di OPD baru)
        $db->table('pegawai')->where('id_pegawai', $id_pegawai)->update([
            'id_opd' => $id_opd_baru,
            'id_lokasi' => null 
        ]);

        return $this->response->setJSON(['status' => 'success', 'message' => 'Pegawai berhasil dipindahkan ke OPD baru.']);
    }

    public function ajax_list()
    {
        $db = \Config\Database::connect();
        $request = \Config\Services::request();
        $level = session()->get('level');
        $id_opd_session = session()->get('id_opd');
        $filter_opd = $request->getPost('filter_opd');

        $builder = $db->table('pegawai')
            ->select('pegawai.*, opd.nama_opd')
            ->join('opd', 'pegawai.id_opd = opd.id_opd');

        if ($level == 'opd') {
            $builder->where('pegawai.id_opd', $id_opd_session);
        } elseif (!empty($filter_opd)) {
            $builder->where('pegawai.id_opd', $filter_opd);
        }

        $searchValue = $request->getPost('search')['value'];
        if ($searchValue) {
            $builder->groupStart()->like('pegawai.nama_lengkap', $searchValue)->orLike('pegawai.nip', $searchValue)->groupEnd();
        }

        $totalFiltered = $builder->countAllResults(false);
        $start = $request->getPost('start');
        $length = $request->getPost('length');

        //$builder->orderBy("CASE 
        // WHEN TRIM(eselon) = 'II.a' THEN 1 WHEN TRIM(eselon) = 'II.b' THEN 2
        //WHEN TRIM(eselon) = 'III.a' THEN 3 WHEN TRIM(eselon) = 'III.b' THEN 4
        //WHEN TRIM(eselon) = 'IV.a' THEN 5 WHEN TRIM(eselon) = 'IV.b' THEN 6
        //WHEN level_jabatan LIKE '%Fungsional%' THEN 7
        //WHEN level_jabatan LIKE '%Staf%' OR TRIM(eselon) = 'Non Eselon' THEN 8
        //WHEN TRIM(eselon) = '-' THEN 9 ELSE 10 END", "ASC", false);

    

        $builder->orderBy('nama_lengkap', 'ASC');
        $result = $builder->limit($length, $start)->get()->getResult();

        $data = [];
        $no = $start + 1;
        foreach ($result as $p) {
            $status_wajah = !empty($p->face_vector) ? '<span class="badge bg-success-subtle text-success px-3">AKTIF</span>' : '<span class="badge bg-danger-subtle text-danger px-3">BELUM ADA</span>';

            $btnHapusWajah = '';
            if (!empty($p->face_vector) && $level == 'kabupaten') {
                $btnHapusWajah = '<a href="' . base_url('pegawai/hapus_wajah/' . $p->id_pegawai) . '" 
                            class="btn btn-sm btn-white border text-danger" 
                            onclick="return confirm(\'Hapus data biometrik wajah pegawai ini?\')" 
                            title="Hapus Wajah">
                            <i class="fas fa-user-slash"></i>
                          </a>';
            }

            $label_lokasi = "Kantor Induk";
            if (!empty($p->id_lokasi)) {
                $count = count(explode(',', $p->id_lokasi));
                $label_lokasi = ($count > 1) ? '<span class="badge bg-info">' . $count . ' Lokasi Terdaftar</span>' : 'Lokasi Khusus';
            }

            // --- TOMBOL LOKASI ---
            $btnLokasi = '';
            // --- [BARU] TOMBOL TRANSFER (HANYA ADMIN KABUPATEN) ---
            $btnTransfer = '';

            if ($level == 'kabupaten') {
                $btnLokasi = '<button onclick="openLokasi(\'' . $p->id_pegawai . '\', \'' . $p->id_opd . '\', \'' . $p->nama_lengkap . '\', \'' . $p->id_lokasi . '\')" class="btn btn-sm btn-white border text-info" title="Penugasan Lokasi"><i class="fas fa-map-marker-alt"></i></button>';
                
                // Tombol Transfer
                $btnTransfer = '<button onclick="openTransfer(\'' . $p->id_pegawai . '\', \'' . $p->nama_lengkap . '\', \'' . $p->id_opd . '\')" class="btn btn-sm btn-white border text-dark" title="Pindah OPD (Transfer)"><i class="fas fa-exchange-alt"></i></button>';
            } else {
                $btnLokasi = '<button class="btn btn-sm btn-white border text-muted opacity-50" title="Hanya Admin Kabupaten" disabled><i class="fas fa-map-marker-alt"></i></button>';
            }

            $opsi = '<div class="btn-group shadow-sm">' .
                $btnHapusWajah .
                '<button onclick="openEnroll(\'' . $p->id_pegawai . '\', \'' . $p->nama_lengkap . '\')" class="btn btn-sm btn-white border text-primary" title="Registrasi Wajah"><i class="fas fa-camera"></i></button>' .
                $btnLokasi .
                $btnTransfer . // Tombol Transfer Masuk Sini
                '<button onclick="openEdit(\'' . $p->id_pegawai . '\')" class="btn btn-sm btn-white border text-warning" title="Edit Data"><i class="fas fa-edit"></i></button>
            <a href="' . base_url('pegawai/hapus/' . $p->id_pegawai) . '" class="btn btn-sm btn-white border text-danger" onclick="return confirm(\'Hapus?\')" title="Hapus Pegawai"><i class="fas fa-trash"></i></a>
            </div>';

            $row = [];
            $row[] = '<span class="ps-3 small text-muted">' . $no++ . '.</span>';
            $row[] = '<div><div class="fw-bold small">' . $p->nama_lengkap . '</div><div class="text-muted small" style="font-size: 10px;">NIP. ' . $p->nip . '</div></div>';

            $row[] = '<div>
                    <div class="small fw-bold text-dark">' . $p->jabatan . '</div>
                    <div class="text-muted" style="font-size: 10px;"><i class="fas fa-landmark me-1"></i>' . $p->nama_opd . '</div>
                    <div class="text-primary fw-bold" style="font-size: 9px;"><i class="fas fa-building me-1"></i>' . $label_lokasi . '</div>
                  </div>';

            $row[] = '<div class="text-center"><span class="badge bg-secondary">' . $p->level_jabatan . '</span></div>';
            $row[] = '<div class="text-center"><span class="badge bg-info-subtle text-info">' . ($p->status_asn ?? '-') . '</span></div>';
            $row[] = $status_wajah;
            $row[] = $opsi;
            $data[] = $row;
        }

        return $this->response->setJSON([
            "draw" => intval($request->getPost('draw')),
            "recordsTotal" => $db->table('pegawai')->countAllResults(),
            "recordsFiltered" => $totalFiltered,
            "data" => $data
        ]);
    }

    public function simpan()
    {
        $db = \Config\Database::connect();
        $nip_input = $this->request->getPost('nip');
        $cek_nip = $db->table('pegawai')->where('nip', $nip_input)->get()->getRow();

        if ($cek_nip) {
            return redirect()->back()
                ->withInput()
                ->with('error', 'Gagal menyimpan! NIP ' . $nip_input . ' sudah terdaftar di sistem.');
        }

        $data = [
            'id_opd'        => $this->request->getPost('id_opd'),
            'nip'           => $nip_input,
            'nama_lengkap'  => $this->request->getPost('nama_lengkap'),
            //'jabatan'       => $this->request->getPost('jabatan'),
            'level_jabatan' => $this->request->getPost('level_jabatan'),
            //'pangkat'       => $this->request->getPost('pangkat'),
            //'eselon'        => $this->request->getPost('eselon'),
            'status_asn'    => $this->request->getPost('status_asn'),
            'password'      => password_hash($this->request->getPost('password'), PASSWORD_DEFAULT),
        ];

        $db->table('pegawai')->insert($data);
        return redirect()->to('pegawai')->with('success', 'Pegawai baru berhasil ditambahkan.');
    }

    public function update()
    {
        $db = \Config\Database::connect();
        $id = $this->request->getPost('id_pegawai');

        $data = [
            'id_opd'        => $this->request->getPost('id_opd'),
            'nip'           => $this->request->getPost('nip'),
            'nama_lengkap'  => $this->request->getPost('nama_lengkap'),
            //'jabatan'       => $this->request->getPost('jabatan'),
            'level_jabatan' => $this->request->getPost('level_jabatan'),
            //'pangkat'       => $this->request->getPost('pangkat'),
            //'eselon'        => $this->request->getPost('eselon'),
            'status_asn'    => $this->request->getPost('status_asn'),
        ];

        if ($this->request->getPost('password')) {
            $data['password'] = password_hash($this->request->getPost('password'), PASSWORD_DEFAULT);
        }

        $db->table('pegawai')->where('id_pegawai', $id)->update($data);
        return redirect()->to('pegawai')->with('success', 'Data pegawai berhasil diperbarui.');
    }

    public function edit_data($id)
    {
        $db = \Config\Database::connect();
        $data = $db->table('pegawai')->where('id_pegawai', $id)->get()->getRowArray();
        return $this->response->setJSON($data);
    }

    public function hapus($id)
    {
        $db = \Config\Database::connect();
        $db->table('pegawai')->where('id_pegawai', $id)->delete();
        return redirect()->to('pegawai')->with('success', 'Data pegawai berhasil dihapus.');
    }

    public function simpan_face_vector()
    {
        $db = \Config\Database::connect();
        $id = $this->request->getPost('id_pegawai');
        $vector = $this->request->getPost('face_vector');
        $db->table('pegawai')->where('id_pegawai', $id)->update(['face_vector' => $vector]);
        return $this->response->setJSON(['status' => 'success', 'msg' => 'Wajah Berhasil Disimpan!']);
    }

    public function ajax_generate_password()
    {
        if (session()->get('level') != 'kabupaten') {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Akses ditolak!']);
        }

        $db = \Config\Database::connect();
        $limit = 50;
        $query_count = $db->table('pegawai')
            ->groupStart()
            ->where('CHAR_LENGTH(password) <', 60)
            ->orWhere('password', NULL)
            ->groupEnd();

        $total_sisa = $query_count->countAllResults(false);
        $pegawai = $query_count->limit($limit)->get()->getResultArray();

        if (empty($pegawai)) {
            return $this->response->setJSON(['status' => 'finish', 'message' => 'Semua password sudah aman.']);
        }

        $berhasil = 0;
        foreach ($pegawai as $p) {
            $hashPassword = password_hash($p['nip'], PASSWORD_DEFAULT);
            $db->table('pegawai')->where('id_pegawai', $p['id_pegawai'])->update(['password' => $hashPassword]);
            $berhasil++;
        }

        return $this->response->setJSON([
            'status' => 'process',
            'processed' => $berhasil,
            'remaining' => $total_sisa - $berhasil
        ]);
    }

    public function hapus_wajah($id)
    {
        $db = \Config\Database::connect();
        $db->table('pegawai')->where('id_pegawai', $id)->update(['face_vector' => null]);
        return redirect()->to('/pegawai')->with('success', 'Data biometrik wajah berhasil direset. Silakan scan ulang.');
    }

    public function import_excel()
    {
        $file = $this->request->getFile('file_excel');

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

        $ext = $file->getClientExtension();
        $reader = ($ext == 'xls') ? new Xls() : new Xlsx();

        try {
            $spreadsheet = $reader->load($file);
            $sheetData = $spreadsheet->getActiveSheet()->toArray();

            $db = \Config\Database::connect();
            $berhasil = 0;
            $skip = 0;

            foreach ($sheetData as $key => $row) {
                if ($key == 0) continue; 
                $nip = str_replace("'", "", trim((string)$row[0]));
                if (empty($nip)) continue;

                $cek = $db->table('pegawai')->where('nip', $nip)->countAllResults();
                if ($cek > 0) {
                    $skip++;
                    continue; 
                }

                $password_default = password_hash($nip, PASSWORD_DEFAULT);

                $data = [
                    'nip'           => $nip,
                    'nama_lengkap'  => $row[1] ?? '', 
                    'id_lokasi'     => $row[2] ?? null, 
                    //'jabatan'       => $row[3] ?? '', 
                    'nomor_hp'      => $row[4] ?? '', 
                    'id_opd'        => $row[5] ?? null, 
                    //'eselon'        => $row[6] ?? '', 
                    'status_asn'    => $row[7] ?? 'PNS', 
                    //'pangkat'       => $row[8] ?? '', 
                    'level_jabatan' => 'Staf', 
                    'password'      => $password_default, 
                ];

                $db->table('pegawai')->insert($data);
                $berhasil++;
            }

            return redirect()->to('pegawai')->with('success', "Import Berhasil! $berhasil data masuk, $skip data NIP sudah ada (dilewati).");
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Gagal membaca file: ' . $e->getMessage());
        }
    }

    public function init_import()
    {
        $file = $this->request->getFile('file_excel');
        if (!$file->isValid()) return $this->response->setJSON(['status' => 'error', 'msg' => 'File tidak valid.']);

        $newName = $file->getRandomName();
        $file->move(WRITEPATH . 'uploads', $newName);
        $filepath = WRITEPATH . 'uploads/' . $newName;

        $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile($filepath);
        $reader->setReadDataOnly(true);
        $spreadsheet = $reader->load($filepath);
        $totalRows = $spreadsheet->getActiveSheet()->getHighestRow();

        return $this->response->setJSON([
            'status' => 'success',
            'temp_file' => $newName,
            'total_rows' => $totalRows - 1 
        ]);
    }

    public function process_import_batch()
    {
        $tempFile = $this->request->getPost('temp_file');
        $offset = (int)$this->request->getPost('offset');
        $limit = 50;
        $filepath = WRITEPATH . 'uploads/' . $tempFile;

        if (!file_exists($filepath)) {
            return $this->response->setJSON(['status' => 'error', 'msg' => 'File sementara tidak ditemukan.']);
        }

        $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile($filepath);
        $reader->setReadDataOnly(true);

        $spreadsheet = $reader->load($filepath);
        $sheetData = $spreadsheet->getActiveSheet()->toArray();

        $db = \Config\Database::connect();
        $berhasil = 0;
        $skip = 0;

        for ($i = $offset + 1; $i < ($offset + 1 + $limit); $i++) {
            if (!isset($sheetData[$i])) break;
            $row = $sheetData[$i];
            $nip = str_replace("'", "", trim((string)($row[0] ?? '')));

            if (empty($nip)) continue;

            $cek = $db->table('pegawai')->where('nip', $nip)->countAllResults();
            if ($cek > 0) {
                $skip++;
                continue;
            }

            $db->table('pegawai')->insert([
                'nip'           => $nip,
                'nama_lengkap'  => $row[1] ?? '',
                'id_lokasi'     => $row[2] ?? null,
                //'jabatan'       => $row[3] ?? '',
                'nomor_hp'      => $row[4] ?? '',
                'id_opd'        => $row[5] ?? null,
                //'eselon'        => $row[6] ?? '',
                'status_asn'    => $row[7] ?? '',
                //'pangkat'       => $row[8] ?? '',
                'level_jabatan' => 'Staf', 
                'password'      => password_hash($nip, PASSWORD_DEFAULT)
            ]);
            $berhasil++;
        }

        $is_finished = ($offset + $limit >= count($sheetData) - 1);
        if ($is_finished) {
            @unlink($filepath);
        }

        return $this->response->setJSON([
            'status' => 'success',
            'processed' => $berhasil + $skip,
            'is_finished' => $is_finished
        ]);
    }
}