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

class Konfigurasi extends Auth_Controller
{
    const TABLE = 'tb_konfigurasi';

    private $system_keys = [
        'nama_aplikasi',
        'nama_perusahaan',
        'alamat_perusahaan',
        'logo_perusahaan',
        'favicon_aplikasi',
        'payroll_mode_periode',
        'payroll_tanggal_gajian',
        'ai_enabled',
        'ai_provider',
        'ai_model',
        'ai_api_key',
        'ai_connection_status',
        'ai_connection_checked_at',
        'ai_connection_message',
    ];

    public function index()
    {
        $data = [
            'page_title'    => 'Konfigurasi Sistem',
            'page_subtitle' => 'Pengaturan identitas aplikasi, perusahaan, dan periode payroll',
            'config'        => $this->get_config($this->system_keys),
        ];
        $this->render('master/konfigurasi/sistem', $data);
    }

    public function simpan()
    {
        if ($this->input->server('REQUEST_METHOD') !== 'POST') {
            redirect('master/konfigurasi');
            return;
        }

        $post = $this->input->post(NULL, TRUE);

        foreach (['nama_aplikasi', 'nama_perusahaan', 'alamat_perusahaan'] as $kunci) {
            if (!isset($post[$kunci])) {
                continue;
            }
            $this->save_config($kunci, trim($post[$kunci]));
        }

        $mode_periode = strtoupper(trim((string) ($post['payroll_mode_periode'] ?? 'CALENDAR')));
        if (!in_array($mode_periode, ['CALENDAR', 'CUSTOM'], true)) {
            $mode_periode = 'CALENDAR';
        }

        $tanggal_gajian = (int) ($post['payroll_tanggal_gajian'] ?? 1);
        if ($tanggal_gajian < 1 || $tanggal_gajian > 31) {
            $tanggal_gajian = 1;
        }

        $this->save_config('payroll_mode_periode', $mode_periode);
        $this->save_config('payroll_tanggal_gajian', (string) $tanggal_gajian);

        $ai_enabled = isset($post['ai_enabled']) && (string) $post['ai_enabled'] === '1' ? '1' : '0';
        $ai_provider = isset($post['ai_provider'])
            ? strtolower(trim((string) $post['ai_provider']))
            : strtolower(trim((string) app_config('ai_provider', 'groq')));
        $ai_provider_allowed = ['groq', 'openai', 'gemini', 'anthropic'];
        if (!in_array($ai_provider, $ai_provider_allowed, true)) {
            $ai_provider = 'groq';
        }
        $ai_model = isset($post['ai_model'])
            ? trim((string) $post['ai_model'])
            : trim((string) app_config('ai_model', ''));
        $ai_api_key = trim((string) ($post['ai_api_key'] ?? ''));

        $old_provider = strtolower(trim((string) app_config('ai_provider', 'groq')));
        $old_model = trim((string) app_config('ai_model', ''));
        $old_api_key = trim((string) app_config('ai_api_key', ''));

        $this->save_config('ai_enabled', $ai_enabled);
        $this->save_config('ai_provider', $ai_provider);
        $this->save_config('ai_model', $ai_model);
        $this->save_config('ai_api_key', $ai_api_key);

        $ai_config_changed = $old_provider !== $ai_provider
            || $old_model !== $ai_model
            || $old_api_key !== $ai_api_key;

        if ($ai_config_changed || $ai_api_key === '' || $ai_enabled !== '1') {
            $status_msg = $ai_api_key === ''
                ? 'API key belum diisi.'
                : 'Konfigurasi AI berubah, lakukan test koneksi ulang.';
            if ($ai_enabled !== '1') {
                $status_msg = 'AI nonaktif.';
            }

            $this->save_config('ai_connection_status', 'DISCONNECTED');
            $this->save_config('ai_connection_message', $status_msg);
            $this->save_config('ai_connection_checked_at', date('Y-m-d H:i:s'));
        }

        $logo_path = $this->handle_upload('logo_perusahaan_file', 'logo_perusahaan', 'logo-perusahaan', 'jpg|jpeg|png|webp|svg');
        if ($logo_path === false) {
            redirect('master/konfigurasi');
            return;
        }

        $favicon_path = $this->handle_upload('favicon_aplikasi_file', 'favicon_aplikasi', 'favicon-aplikasi', 'ico|png|jpg|jpeg|webp|svg');
        if ($favicon_path === false) {
            redirect('master/konfigurasi');
            return;
        }

        audit_log('EDIT', 'Konfigurasi Sistem', 'Update konfigurasi sistem');
        $this->session->set_flashdata('success', 'Konfigurasi sistem berhasil disimpan.');
        redirect('master/konfigurasi');
    }

    public function test_ai_connection()
    {
        if ($this->input->server('REQUEST_METHOD') !== 'POST') {
            return $this->json_response([
                'success' => false,
                'message' => 'Metode request tidak valid.',
            ], 405);
        }

        $provider = strtolower(trim((string) $this->input->post('ai_provider', true)));
        if ($provider === '') {
            $provider = strtolower(trim((string) app_config('ai_provider', 'groq')));
        }

        $model = trim((string) $this->input->post('ai_model', true));
        if ($model === '') {
            $model = trim((string) app_config('ai_model', ''));
        }

        $api_key = trim((string) $this->input->post('ai_api_key', true));
        $enabled = $this->input->post('ai_enabled', true) === '1' ? '1' : '0';

        if (!in_array($provider, ['groq', 'openai', 'gemini', 'anthropic'], true)) {
            $provider = 'groq';
        }

        if ($api_key === '') {
            $this->save_config('ai_enabled', $enabled);
            $this->save_config('ai_provider', $provider);
            $this->save_config('ai_model', $model);
            $this->save_config('ai_api_key', $api_key);
            $this->save_config('ai_connection_status', 'DISCONNECTED');
            $this->save_config('ai_connection_checked_at', date('Y-m-d H:i:s'));
            $this->save_config('ai_connection_message', 'API key belum diisi.');

            return $this->json_response([
                'success' => false,
                'status' => 'DISCONNECTED',
                'message' => 'API key belum diisi.',
                'checked_at' => date('Y-m-d H:i:s'),
            ], 422);
        }

        $this->save_config('ai_enabled', $enabled);
        $this->save_config('ai_provider', $provider);
        $this->save_config('ai_model', $model);
        $this->save_config('ai_api_key', $api_key);

        $test_result = $this->test_provider_connection($provider, $model, $api_key);
        $status = $test_result['success'] ? 'CONNECTED' : 'DISCONNECTED';
        $checked_at = date('Y-m-d H:i:s');
        $message = (string) ($test_result['message'] ?? ($test_result['success'] ? 'Koneksi berhasil.' : 'Koneksi gagal.'));

        $this->save_config('ai_connection_status', $status);
        $this->save_config('ai_connection_checked_at', $checked_at);
        $this->save_config('ai_connection_message', $message);

        audit_log('TEST', 'Konfigurasi AI', 'Provider: ' . strtoupper($provider) . ' | Status: ' . $status . ' | Pesan: ' . $message);

        return $this->json_response([
            'success' => (bool) $test_result['success'],
            'status' => $status,
            'message' => $message,
            'checked_at' => $checked_at,
        ]);
    }

    private function get_config($keys)
    {
        if (empty($keys)) {
            return [];
        }

        $rows = $this->db->where_in('kunci', $keys)->get(self::TABLE)->result();
        $config = [];
        foreach ($rows as $row) {
            $config[$row->kunci] = $row->nilai;
        }

        return $config;
    }

    private function save_config($kunci, $nilai)
    {
        $exists = $this->db->where('kunci', $kunci)->count_all_results(self::TABLE) > 0;
        if ($exists) {
            $this->db->where('kunci', $kunci)
                ->update(self::TABLE, ['nilai' => $nilai, 'updated_at' => date('Y-m-d H:i:s')]);
            return;
        }

        $this->db->insert(self::TABLE, ['kunci' => $kunci, 'nilai' => $nilai]);
    }

    private function handle_upload($field_name, $config_key, $file_prefix, $allowed_types)
    {
        if (empty($_FILES[$field_name]['name'])) {
            return null;
        }

        $upload_dir = FCPATH . 'assets/uploads/settings/';
        if (!is_dir($upload_dir)) {
            mkdir($upload_dir, 0755, true);
        }

        $upload_config = [
            'upload_path'   => $upload_dir,
            'allowed_types' => $allowed_types,
            'max_size'      => 2048,
            'file_ext_tolower' => true,
            'remove_spaces' => true,
            'file_name'     => $file_prefix . '-' . date('YmdHis'),
        ];

        $this->load->library('upload');
        $this->upload->initialize($upload_config);

        if (!$this->upload->do_upload($field_name)) {
            $this->session->set_flashdata('error', 'Upload gagal: ' . strip_tags($this->upload->display_errors('', '')));
            return false;
        }

        $data = $this->upload->data();
        $new_relative_path = 'assets/uploads/settings/' . $data['file_name'];
        $old_relative_path = trim((string) app_config($config_key, ''));

        $this->save_config($config_key, $new_relative_path);

        if ($old_relative_path !== '' && $old_relative_path !== $new_relative_path) {
            $old_full_path = FCPATH . ltrim($old_relative_path, '/');
            if (is_file($old_full_path)) {
                @unlink($old_full_path);
            }
        }

        return $new_relative_path;
    }

    private function test_provider_connection($provider, $model, $api_key)
    {
        if (!function_exists('curl_init')) {
            return [
                'success' => false,
                'message' => 'Ekstensi cURL tidak tersedia di server.',
            ];
        }

        if ($provider === 'groq') {
            $url = 'https://api.groq.com/openai/v1/models';
            if ($model !== '') {
                $url = 'https://api.groq.com/openai/v1/models/' . rawurlencode($model);
            }
            return $this->curl_request('GET', $url, [
                'Authorization: Bearer ' . $api_key,
                'Content-Type: application/json',
            ]);
        }

        if ($provider === 'openai') {
            $url = 'https://api.openai.com/v1/models';
            if ($model !== '') {
                $url = 'https://api.openai.com/v1/models/' . rawurlencode($model);
            }
            return $this->curl_request('GET', $url, [
                'Authorization: Bearer ' . $api_key,
                'Content-Type: application/json',
            ]);
        }

        if ($provider === 'gemini') {
            $url = 'https://generativelanguage.googleapis.com/v1beta/models?key=' . rawurlencode($api_key);
            return $this->curl_request('GET', $url, [
                'Content-Type: application/json',
            ]);
        }

        if ($provider === 'anthropic') {
            $url = 'https://api.anthropic.com/v1/models';
            return $this->curl_request('GET', $url, [
                'x-api-key: ' . $api_key,
                'anthropic-version: 2023-06-01',
                'Content-Type: application/json',
            ]);
        }

        return [
            'success' => false,
            'message' => 'Provider AI tidak dikenali.',
        ];
    }

    private function curl_request($method, $url, $headers = [], $payload = null)
    {
        $ch = curl_init($url);
        if ($ch === false) {
            return [
                'success' => false,
                'message' => 'Gagal inisialisasi cURL.',
            ];
        }

        $options = [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_TIMEOUT => 20,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_CUSTOMREQUEST => strtoupper($method),
            CURLOPT_HTTPHEADER => $headers,
        ];

        if ($payload !== null) {
            $options[CURLOPT_POSTFIELDS] = is_array($payload) ? json_encode($payload) : (string) $payload;
        }

        curl_setopt_array($ch, $options);
        $raw = curl_exec($ch);
        $errno = curl_errno($ch);
        $error = curl_error($ch);
        $http_code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($errno !== 0) {
            return [
                'success' => false,
                'message' => 'Koneksi gagal: ' . $error,
            ];
        }

        $decoded = json_decode((string) $raw, true);
        if ($http_code >= 200 && $http_code < 300) {
            return [
                'success' => true,
                'message' => 'Koneksi API berhasil.',
                'response' => $decoded,
            ];
        }

        $err_message = 'HTTP ' . $http_code . ' dari provider AI.';
        if (is_array($decoded)) {
            if (!empty($decoded['error']['message'])) {
                $err_message = (string) $decoded['error']['message'];
            } elseif (!empty($decoded['message'])) {
                $err_message = (string) $decoded['message'];
            }
        }

        return [
            'success' => false,
            'message' => $err_message,
            'response' => $decoded,
        ];
    }

    private function json_response($payload, $status_code = 200)
    {
        $this->output
            ->set_status_header($status_code)
            ->set_content_type('application/json', 'utf-8')
            ->set_output(json_encode($payload));
        return;
    }
}
