<?php
// app/Controllers/Backend/DataTransactionController.php
namespace App\Controllers\Backend;

use App\Controllers\BaseController;
use App\Models\TransactionModel;
use App\Models\EventModel;
use App\Models\ChurchModel;
use App\Models\ParticipantModel;
use App\Models\EventPackageModel;
use App\Models\ParticipantFieldValueModel;
use App\Models\EventFieldModel;
use App\Libraries\TransactionService;
use App\Libraries\PdfService;

class DataTransactionController extends BaseController
{
    /**
     * Menampilkan halaman daftar transaksi dengan filter.
     */
    public function index()
    {
        $transactionModel = new TransactionModel();
        $eventModel = new EventModel();
        $churchModel = new ChurchModel();

        $filters = [
            'user_name'      => $this->request->getGet('user_name'),
            'invoice_number' => $this->request->getGet('invoice_number'),
            'event_id'       => $this->request->getGet('event_id'),
            'church_id'      => $this->request->getGet('church_id'),
            'payment_status' => $this->request->getGet('payment_status'),
            'payment_method'   => $this->request->getGet('payment_method'),
            'start_date'     => $this->request->getGet('start_date'),
            'end_date'       => $this->request->getGet('end_date')
        ];

        $adminChurchIds = getAdminChurchIds(session()->get('user_id'));
        if ($adminChurchIds !== null) {
            $filters['admin_church_ids'] = $adminChurchIds;
        }
        $data['transactions'] = $transactionModel->search($filters);

        $churchQuery = $churchModel;
        if ($adminChurchIds !== null) {
            $churchQuery->whereIn('id', $adminChurchIds);
        }
        $data['churches'] = $churchQuery->findAll();

        $eventQuery = $eventModel;
        if ($adminChurchIds !== null) {
            $eventQuery->groupStart()
                       ->whereIn('church_id', $adminChurchIds)
                       ->orWhere('church_id IS NULL')
                       ->groupEnd();
        }
        $data['events'] = $eventModel->findAll();
        $data['payment_status'] = get_database_enum_values('transactions','payment_status');
        $data['payment_method'] = get_database_enum_values('event_payment_methods','method');
        
    
        
        $data['pager'] = $transactionModel->pager;
        $data['filters'] = $filters;
        $data['pageTitle'] = lang('Admin/Transactions.pageTitle');

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

    /**
     * Menampilkan halaman detail transaksi.
     */
    public function show($uuid = null)
    {
        $transactionService = new TransactionService();
        $data = $transactionService->getTransactionData($uuid); // Hapus requesterId, karena ini admin

        if (!$data) {
            return redirect()->route('admin.transactions.index')->with('error', 'Transaction not found.');
        }

        $data['pageTitle'] = lang('Admin/Transactions.detailPageTitle', [$data['transaction']->invoice_number]);
        $data['statusOptions'] = [
            'pending' => ['paid', 'rejected'], 'paid' => ['canceled'],
            'rejected'=> ['deleted'], 'canceled'=> ['deleted'],
        ];

        return view('backend/transactions/show', $data);
    }

    /**
     * Memproses update status transaksi.
     */
    public function updateStatus($uuid = null)
    {
        $transaction = $this->_findTransactionByUuid($uuid);
        if (!$transaction) {
            return redirect()->route('admin.transactions.index')->with('error', 'Transaction not found.');
        }

        $newStatus = $this->request->getPost('status');
        $notifyUser = (bool)$this->request->getPost('notify_user');
        $notes = $this->request->getPost('notes');
        $adminId = session()->get('user_id');

        $transactionService = new TransactionService();
        $success = $transactionService->changeStatus($transaction->id, $newStatus, $adminId, $notifyUser, $notes);

        if ($success) {
            return redirect()->to(route_to('admin.transactions.show', $uuid))->with('success', lang('Admin/Transactions.updateSuccess'));
        }

        return redirect()->back()->with('error', lang('Admin/Transactions.updateFailed'));
    }
    
    /**
     * Menampilkan form untuk mengedit data seorang peserta.
     */
    public function editParticipant($participantId = null)
    {
        $participantModel = new ParticipantModel();
        $participant = $participantModel->find($participantId);

        if (!$participant) {
            return redirect()->back()->with('error', lang('Admin/Transactions.participantNotFound'));
        }

        $data['transaction'] = (new TransactionModel())->find($participant->transaction_id);
        $data['package'] = (new EventPackageModel())->find($participant->event_package_id);
        $data['churches'] = (new ChurchModel())->where('is_active', 1)->orderBy('name', 'ASC')->findAll();
        $customFields = (new \App\Models\EventFieldModel())->where('event_id', $data['transaction']->event_id)->orderBy('sort_order', 'ASC')->findAll();
        foreach ($customFields as $field) {
            if ($field->type === 'select' && !empty($field->options)) {
                $field->options = json_decode($field->options, true);
            }
        }
        $data['customFields'] = $customFields;
        
        $fieldValues = (new ParticipantFieldValueModel())->where('participant_id', $participantId)->findAll();
        $data['participantValues'] = array_column($fieldValues, 'value', 'event_field_id');
        
        $data['participant'] = $participant;
        $data['pageTitle'] = lang('Admin/Transactions.editParticipantTitle', [$participant->name]);

        return view('backend/transactions/edit_participant', $data);
    }

    /**
     * Memproses update data peserta.
     */
    public function updateParticipant($participantId = null)
    {
        $participantModel = new ParticipantModel();
        $participant = $participantModel->find($participantId);

        if (!$participant) {
            return redirect()->route('admin.transactions.index')->with('error', lang('Admin/Transactions.participantNotFound'));
        }

        $transaction = (new TransactionModel())->find($participant->transaction_id);
        
        $isKtaFilled = !empty($this->request->getPost('kta_number'));
        $ktaRules = 'permit_empty';
        if ($isKtaFilled) {
            $ktaRules .= "|is_unique_participant_kta_except[{$transaction->event_id},{$participantId}]|validate_kta_and_birthdate[birth_date]";
        }

        $rules = [
            'name' => 'required|alpha_space|min_length[3]|max_length[255]',
            'phone_number' => "required|regex_match[/^\+[1-9]\d{1,14}$/]",
            'email' => 'required|valid_email',
            'church_id' => 'required',
            'kta_number' => $ktaRules,
            'birth_date' => 'permit_empty|valid_date',
        ];

        if ($this->request->getPost('church_id') === 'other') {
            $rules['church_name'] = 'required|string|max_length[150]';
        }

        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $db = \Config\Database::connect();
        $db->transStart();
        
        $participantData = [
            'name' => $this->request->getPost('name'), 'email' => $this->request->getPost('email'),
            'phone_number' => $this->request->getPost('phone_number'), 'gender' => $this->request->getPost('gender'),
            'church_id' => $this->request->getPost('church_id') === 'other' ? null : $this->request->getPost('church_id'), 
            'church_name' => $this->request->getPost('church_id') === 'other' ? $this->request->getPost('church_name') : null,
            'kta_number' => $this->request->getPost('kta_number') ?? null,
            'birth_date' => !empty($this->request->getPost('birth_date')) ? $this->request->getPost('birth_date') : null,
        ];
        $participantModel->update($participantId, $participantData);

        $fieldValueModel = new ParticipantFieldValueModel();
        $fieldValueModel->where('participant_id', $participantId)->delete();
        $customFieldsData = $this->request->getPost('custom') ?? [];
        $valuesToInsert = [];
        foreach ($customFieldsData as $fieldId => $value) {
            if (empty($value) && $value !== '0') continue;
            $valueToSave = is_array($value) ? json_encode($value) : $value;
            $valuesToInsert[] = ['participant_id' => $participantId, 'event_field_id' => $fieldId, 'value' => $valueToSave];
        }
        if (!empty($valuesToInsert)) {
            $fieldValueModel->insertBatch($valuesToInsert);
        }
        
        $db->transComplete();

        if ($db->transStatus() === false) {
            return redirect()->back()->withInput()->with('error', lang('Transaction.error_db_save'));
        }
        
        return redirect()->to(route_to('admin.transactions.show', $transaction->uuid))->with('success', lang('Admin/Transactions.updateParticipantSuccess'));
    }

    /**
     * Memproses permintaan untuk mengirim ulang notifikasi.
     */
    public function resendNotification($uuid = null)
    {
        $transaction = $this->_findTransactionByUuid($uuid);
        if (!$transaction) {
            return redirect()->route('admin.transactions.index')->with('error', 'Transaction not found.');
        }

        $transactionService = new TransactionService();
        $success = $transactionService->resendNotification($transaction->id);

        if ($success) {
            return redirect()->to(route_to('admin.transactions.show', $uuid))->with('success', lang('Admin/Transactions.notificationSent'));
        }

        return redirect()->back()->with('error', lang('Admin/Transactions.notificationFailed'));
    }

    public function downloadPdf($uuid = null)
    {
        $pdfService = new PdfService();
        
        $result = $pdfService->streamTicket($uuid, null);

        if (is_array($result) && isset($result['error'])) {
            return redirect()->back()->with('error', $result['error']);
        }
        
        return;
    }

    /**
     * Helper privat untuk mencari transaksi berdasarkan UUID.
     */
    private function _findTransactionByUuid(?string $uuid)
    {
        if (!$uuid) {
            return null;
        }
        return (new TransactionModel())->where('uuid', $uuid)->first();
    }
}