<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Pendaftaran_online extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->library(['form_validation']);
        $this->load->database();
    }

    public function index() {
        // Load data poli dan dokter langsung dari database
        $data = [
            'list_poli' => $this->db->get_where('tb_poli', ['status' => 1])->result(),
            'list_dokter' => $this->get_all_dokter()
        ];
        $this->load->view('pendaftaran_online', $data);
    }

    // Method untuk get semua dokter aktif
    private function get_all_dokter() {
        return $this->db->select('d.dokter_id, d.id_poli, p.nama_lengkap AS nama_dokter')
            ->from('tb_dokter d')
            ->join('tb_petugas p', 'p.petugas_id = d.id_petugas', 'left')
            ->where('p.status_aktif', 1)
            ->order_by('p.nama_lengkap', 'ASC')
            ->get()->result();
    }

    // Method untuk get dokter by poli
    private function get_dokter_by_poli($poli_id) {
        return $this->db->select('d.dokter_id, d.id_poli, p.nama_lengkap AS nama_dokter')
            ->from('tb_dokter d')
            ->join('tb_petugas p', 'p.petugas_id = d.id_petugas', 'left')
            ->where('d.id_poli', $poli_id)
            ->where('p.status_aktif', 1)
            ->order_by('p.nama_lengkap', 'ASC')
            ->get()->result();
    }

    // Method untuk get dokter by ID
    private function get_dokter_by_id($dokter_id) {
        return $this->db->select('d.dokter_id, d.id_poli, p.nama_lengkap AS nama_dokter')
            ->from('tb_dokter d')
            ->join('tb_petugas p', 'p.petugas_id = d.id_petugas', 'left')
            ->where('d.dokter_id', $dokter_id)
            ->where('p.status_aktif', 1)
            ->get()->row();
    }

    // Method untuk generate ID Pasien
    private function generate_pasien_id() {
        $last = $this->db->select('pasien_id')
            ->from('tb_pasien')
            ->like('pasien_id', 'P-', 'after')
            ->order_by('LENGTH(pasien_id)', 'DESC')
            ->order_by('pasien_id', 'DESC')
            ->get()->row();
        
        if ($last) {
            $last_number = intval(substr($last->pasien_id, 2));
            $next_number = $last_number + 1;
        } else {
            $next_number = 1;
        }
        
        return 'P-' . str_pad($next_number, 4, '0', STR_PAD_LEFT);
    }

    // Method untuk generate RME No
    private function generate_rme_no() {
        $year = date('Y');
        $last = $this->db->select('rme_no')
            ->from('tb_pasien')
            ->like('rme_no', 'RME-' . $year, 'after')
            ->order_by('LENGTH(rme_no)', 'DESC')
            ->order_by('rme_no', 'DESC')
            ->get()->row();
        
        if ($last && strpos($last->rme_no, 'RME-' . $year) !== false) {
            $last_number = intval(substr($last->rme_no, -4));
            $next_number = $last_number + 1;
        } else {
            $next_number = 1;
        }
        
        return 'RME-' . $year . '-' . str_pad($next_number, 4, '0', STR_PAD_LEFT);
    }

    // Method untuk generate UUID
    private function generate_uuid() {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }

    // Method untuk generate nomor reservasi
    private function generate_nomor_reservasi() {
        $prefix = 'RSV';
        $date = date('Ymd');
        
        $this->db->where('DATE(created_at)', date('Y-m-d'));
        $this->db->order_by('nomor_reservasi', 'DESC');
        $last = $this->db->get('tb_registrasi')->row();
        
        if ($last && !empty($last->nomor_reservasi)) {
            $last_number = intval(substr($last->nomor_reservasi, -4));
            $next_number = $last_number + 1;
        } else {
            $next_number = 1;
        }
        
        return $prefix . $date . str_pad($next_number, 4, '0', STR_PAD_LEFT);
    }

    // Method untuk generate kode verifikasi
    private function generate_kode_verifikasi() {
        return strtoupper(substr(md5(uniqid()), 0, 6));
    }

    // Method untuk get pasien by NIK
    private function get_pasien_by_nik($nik) {
        return $this->db->get_where('tb_pasien', ['nik' => $nik, 'status_aktif' => 1])->row();
    }

    // Method untuk get pasien by ID
    private function get_pasien_by_id($pasien_id) {
        return $this->db->get_where('tb_pasien', ['pasien_id' => $pasien_id])->row();
    }

    // Method untuk get pasien by RME dan bulan lahir
    private function get_pasien_by_rme_and_birth_month($rme_no, $bulan_lahir) {
        return $this->db->select('*')
            ->from('tb_pasien')
            ->where('rme_no', $rme_no)
            ->where('MONTH(tanggal_lahir)', $bulan_lahir)
            ->where('status_aktif', 1)
            ->get()->row();
    }

    public function simpan_pasien_baru() {
        // Set rules validasi
        $this->form_validation->set_rules('nik', 'NIK', 'required|exact_length[16]');
        $this->form_validation->set_rules('nama_lengkap', 'Nama Lengkap', 'required|max_length[100]');
        $this->form_validation->set_rules('jenis_kelamin', 'Jenis Kelamin', 'required');
        $this->form_validation->set_rules('id_poli', 'Poli', 'required');
        $this->form_validation->set_rules('tanggal_periksa', 'Tanggal Periksa', 'required');

        if ($this->form_validation->run() == FALSE) {
            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => validation_errors()
                ]));
            return;
        }

        try {
            $this->db->trans_begin();

            $data_pasien = $this->input->post();
            
            // Cek apakah NIK sudah ada
            $existing_pasien = $this->get_pasien_by_nik($data_pasien['nik']);
            if ($existing_pasien) {
                throw new Exception('NIK sudah terdaftar dalam sistem');
            }

            // Generate ID Pasien dan RME No
            $pasien_id = $this->generate_pasien_id();
            $rme_no = $this->generate_rme_no();

            // Siapkan data pasien lengkap untuk tb_pasien
            $pasien_data = [
                'pasien_id' => $pasien_id,
                'rme_no' => $rme_no,
                'nik' => $data_pasien['nik'],
                'nama_lengkap' => $data_pasien['nama_lengkap'],
                'tempat_lahir' => $data_pasien['tempat_lahir'] ?? null,
                'tanggal_lahir' => $data_pasien['tanggal_lahir'] ?? null,
                'jenis_kelamin' => $data_pasien['jenis_kelamin'],
                'golongan_darah' => $data_pasien['golongan_darah'] ?? null,
                'alamat' => $data_pasien['alamat'] ?? null,
                'no_telp' => $data_pasien['no_telp'] ?? null,
                'email' => $data_pasien['email'] ?? null,
                'pekerjaan' => $data_pasien['pekerjaan'] ?? null,
                'jenis_asuransi' => $data_pasien['jenis_pembayaran'] ?? 'UMUM',
                'no_asuransi' => $data_pasien['no_asuransi'] ?? null,
                'status_aktif' => 1,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];

            // Simpan pasien ke tabel tb_pasien
            $insert_pasien = $this->db->insert('tb_pasien', $pasien_data);
            
            if (!$insert_pasien) {
                throw new Exception('Gagal menyimpan data pasien');
            }

            // Buat registrasi online
            $registrasi_id = $this->generate_uuid();
            $nomor_reservasi = $this->generate_nomor_reservasi();
            $kode_verifikasi = $this->generate_kode_verifikasi();

            // Get nama poli dan dokter
            $poli = $this->db->get_where('tb_poli', ['poli_id' => $data_pasien['id_poli']])->row();
            $dokter = $data_pasien['id_dokter'] ? $this->get_dokter_by_id($data_pasien['id_dokter']) : null;

            $registrasi_data = [
                'registrasi_id' => $registrasi_id,
                'nomor_reservasi' => $nomor_reservasi,
                'id_pasien' => $pasien_id,
                'id_poli' => $data_pasien['id_poli'],
                'id_dokter' => $data_pasien['id_dokter'] ?? null,
                'tipe_pembayaran' => $data_pasien['jenis_pembayaran'] ?? 'UMUM',
                'no_asuransi' => $data_pasien['no_asuransi'] ?? null,
                'tanggal_registrasi' => $data_pasien['tanggal_periksa'],
                'jam_registrasi' => date('H:i:s'),
                'cara_masuk' => 'Datang Sendiri',
                'jenis_kunjungan' => $data_pasien['jenis_kunjungan'] ?? 'SAKIT',
                'jenis_perawatan' => 'RAWAT JALAN',
                'registrasi_mandiri' => 1,
                'sumber_registrasi' => 'ONLINE',
                'kode_verifikasi' => $kode_verifikasi,
                'status_verifikasi' => 'BELUM',
                'status_registrasi' => 'TERDAFTAR',
                'status_kehadiran' => 'TERDAFTAR',
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];

            $insert_registrasi = $this->db->insert('tb_registrasi', $registrasi_data);
            
            if (!$insert_registrasi) {
                throw new Exception('Gagal menyimpan data registrasi');
            }

            if ($this->db->trans_status() === FALSE) {
                $this->db->trans_rollback();
                throw new Exception('Gagal menyimpan data transaksi');
            }

            $this->db->trans_commit();

            // Kirim konfirmasi (email/SMS)
            $this->_send_confirmation($registrasi_data, $pasien_data, $poli, $dokter);

            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'message' => 'Pendaftaran berhasil. Data pasien baru telah disimpan.',
                    'nomor_antrian' => $nomor_reservasi,
                    'data' => [
                        'nama_lengkap' => $pasien_data['nama_lengkap'],
                        'rme_no' => $rme_no,
                        'nama_poli' => $poli->nama_poli ?? '-',
                        'nama_dokter' => $dokter->nama_dokter ?? '-',
                        'tanggal_periksa' => $data_pasien['tanggal_periksa'],
                        'waktu_periksa' => '08:00 - 12:00',
                        'nomor_reservasi' => $nomor_reservasi,
                        'kode_verifikasi' => $kode_verifikasi
                    ]
                ]));

        } catch (Exception $e) {
            $this->db->trans_rollback();
            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => 'Terjadi kesalahan: ' . $e->getMessage()
                ]));
        }
    }

    public function simpan_pasien_lama() {
        $this->form_validation->set_rules('id_pasien', 'Pasien', 'required');
        $this->form_validation->set_rules('id_poli', 'Poli', 'required');
        $this->form_validation->set_rules('tanggal_periksa', 'Tanggal Periksa', 'required');

        if ($this->form_validation->run() == FALSE) {
            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => validation_errors()
                ]));
            return;
        }

        try {
            $this->db->trans_begin();

            $data = $this->input->post();
            $pasien = $this->get_pasien_by_id($data['id_pasien']);
            
            if (!$pasien) {
                throw new Exception('Data pasien tidak ditemukan');
            }

            // Buat registrasi online
            $registrasi_id = $this->generate_uuid();
            $nomor_reservasi = $this->generate_nomor_reservasi();
            $kode_verifikasi = $this->generate_kode_verifikasi();

            // Get nama poli dan dokter
            $poli = $this->db->get_where('tb_poli', ['poli_id' => $data['id_poli']])->row();
            $dokter = $data['id_dokter'] ? $this->get_dokter_by_id($data['id_dokter']) : null;

            $registrasi_data = [
                'registrasi_id' => $registrasi_id,
                'nomor_reservasi' => $nomor_reservasi,
                'id_pasien' => $data['id_pasien'],
                'id_poli' => $data['id_poli'],
                'id_dokter' => $data['id_dokter'] ?? null,
                'tipe_pembayaran' => $pasien->jenis_asuransi ?? 'UMUM',
                'no_asuransi' => $pasien->no_asuransi ?? null,
                'tanggal_registrasi' => $data['tanggal_periksa'],
                'jam_registrasi' => date('H:i:s'),
                'cara_masuk' => 'Datang Sendiri',
                'jenis_kunjungan' => $data['jenis_kunjungan'] ?? 'SAKIT',
                'jenis_perawatan' => 'RAWAT JALAN',
                'registrasi_mandiri' => 1,
                'sumber_registrasi' => 'ONLINE',
                'kode_verifikasi' => $kode_verifikasi,
                'status_verifikasi' => 'BELUM',
                'status_registrasi' => 'TERDAFTAR',
                'status_kehadiran' => 'TERDAFTAR',
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];

            $insert_registrasi = $this->db->insert('tb_registrasi', $registrasi_data);
            
            if (!$insert_registrasi) {
                throw new Exception('Gagal menyimpan data registrasi');
            }

            $this->db->trans_commit();

            // Kirim konfirmasi
            $this->_send_confirmation($registrasi_data, (array)$pasien, $poli, $dokter);

            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'message' => 'Pendaftaran berhasil',
                    'nomor_antrian' => $nomor_reservasi,
                    'data' => [
                        'nama_lengkap' => $pasien->nama_lengkap,
                        'rme_no' => $pasien->rme_no,
                        'nama_poli' => $poli->nama_poli ?? '-',
                        'nama_dokter' => $dokter->nama_dokter ?? '-',
                        'tanggal_periksa' => $data['tanggal_periksa'],
                        'waktu_periksa' => '08:00 - 12:00',
                        'nomor_reservasi' => $nomor_reservasi,
                        'kode_verifikasi' => $kode_verifikasi
                    ]
                ]));

        } catch (Exception $e) {
            $this->db->trans_rollback();
            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => 'Terjadi kesalahan: ' . $e->getMessage()
                ]));
        }
    }

    public function cari_pasien_lama() {
        $rme_no = $this->input->post('rme_no');
        $bulan_lahir = $this->input->post('bulan_lahir');

        if (!$rme_no || !$bulan_lahir) {
            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => 'No. RM dan bulan lahir harus diisi'
                ]));
            return;
        }

        $pasien = $this->get_pasien_by_rme_and_birth_month($rme_no, $bulan_lahir);
        
        if ($pasien) {
            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'data' => $pasien
                ]));
        } else {
            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => 'Pasien tidak ditemukan. Pastikan No. RM dan bulan lahir sesuai.'
                ]));
        }
    }

    public function dokter_by_poli($poli_id) {
        $dokter = $this->get_dokter_by_poli($poli_id);
        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode($dokter));
    }

    private function _send_confirmation($registrasi, $pasien, $poli, $dokter) {
        // Implementasi pengiriman email/SMS
        $message = "Halo {$pasien['nama_lengkap']},\n\n";
        $message .= "Pendaftaran online Anda berhasil!\n\n";
        $message .= "📋 DETAIL REGISTRASI:\n";
        $message .= "• No. RM: {$pasien['rme_no']}\n";
        $message .= "• Nomor Reservasi: {$registrasi['nomor_reservasi']}\n";
        $message .= "• Kode Verifikasi: {$registrasi['kode_verifikasi']}\n";
        $message .= "• Tanggal Periksa: {$registrasi['tanggal_registrasi']}\n";
        $message .= "• Poli: " . ($poli->nama_poli ?? '-') . "\n";
        $message .= "• Dokter: " . ($dokter->nama_dokter ?? '-') . "\n\n";
        $message .= "Silakan datang ke rumah sakit 15 menit sebelum jadwal dengan membawa:\n";
        $message .= "1. KTP asli\n";
        $message .= "2. Kartu BPJS/Asuransi (jika ada)\n";
        $message .= "3. Kode verifikasi di atas\n\n";
        $message .= "Terima kasih.";

        // Log untuk testing
        log_message('info', 'Konfirmasi registrasi online: ' . $message);

        // Untuk development, simpan ke file
        $filename = FCPATH . 'logs/konfirmasi_' . $registrasi['nomor_reservasi'] . '.txt';
        if (!is_dir(FCPATH . 'logs')) {
            mkdir(FCPATH . 'logs', 0755, true);
        }
        file_put_contents($filename, $message);
    }
}
