<?php

namespace App\Models;

use CodeIgniter\Model;

class PaymentTransactionModel extends Model
{
    protected $table = 'payment_transactions'; // Table name
    protected $primaryKey = 'id';  // Primary key

    // Allowed fields for mass assignment
    protected $allowedFields = [
        'transaction_id',
        'payment_id',               // Reference to payments table (the associated payment)
        'transaction_date',
        'amount',
        'payment_method',
        'payment_status',
        'transaction_fee',
        'payment_reference',
        'semester',
        'school_year',
        'is_full_payment',          // Flag to track full payment status
        'created_at',
        'updated_at'
    ];

    // Set automatic timestamps
    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';

    // Validation rules
    protected $validationRules = [
        'transaction_id' => 'required|is_unique[payment_transactions.transaction_id]',
        'payment_id' => 'required|integer',  // Reference to payment table
        'amount' => 'required|decimal',
        'payment_method' => 'required|string|max_length[50]',
        'payment_status' => 'required|string|max_length[50]',
        'payment_reference' => 'permit_empty|string|max_length[255]',
        'is_full_payment' => 'required|in_list[0,1]', // 0 for installment, 1 for full payment
    ];

    // Custom error messages
    protected $validationMessages = [
        'transaction_id' => [
            'required' => 'The transaction ID is required.',
            'is_unique' => 'The transaction ID must be unique.',
        ],
        'payment_id' => [
            'required' => 'The payment ID is required.',
            'integer' => 'The payment ID must be an integer.',
        ],
        'amount' => [
            'required' => 'The payment amount is required.',
            'decimal' => 'The payment amount must be a valid decimal number.',
        ],
        'payment_method' => [
            'required' => 'The payment method is required.',
            'max_length' => 'The payment method must not exceed 50 characters.',
        ],
        'payment_status' => [
            'required' => 'The payment status is required.',
            'max_length' => 'The payment status must not exceed 50 characters.',
        ],
        'payment_reference' => [
            'max_length' => 'The payment reference must not exceed 255 characters.',
        ],
        'is_full_payment' => [
            'required' => 'The full payment flag is required.',
            'in_list' => 'The full payment flag must be either 0 (installment) or 1 (full payment).',
        ],
    ];

    /**
     * Get all transactions for a specific payment.
     *
     * @param int $paymentId
     * @return array
     */
    public function getTransactionsByPaymentId($paymentId)
    {
        return $this->where('payment_id', $paymentId)
            ->orderBy('transaction_date', 'DESC')
            ->findAll();
    }

    /**
     * Retrieve a single transaction by its transaction ID.
     *
     * @param string $transactionId
     * @return array|null
     */
    public function getTransactionById($transactionId)
    {
        return $this->where('transaction_id', $transactionId)->first();
    }

    /**
     * Update payment status by transaction ID.
     *
     * @param string $transactionId
     * @param string $status
     * @return bool
     */
    public function updateTransactionStatus($transactionId, $status)
    {
        return $this->update($transactionId, ['payment_status' => $status]);
    }

    /**
     * Get total amount paid for a specific payment.
     *
     * @param int $paymentId
     * @return float
     */
    public function getTotalPaidByPaymentId($paymentId)
    {
        $this->selectSum('amount');
        return $this->where('payment_id', $paymentId)->get()->getRow()->amount;
    }

    /**
     * Update transaction fee for a specific transaction.
     *
     * @param string $transactionId
     * @param float $transactionFee
     * @return bool
     */
    public function updateTransactionFee($transactionId, $transactionFee)
    {
        return $this->update($transactionId, ['transaction_fee' => $transactionFee]);
    }

    /**
     * Get the latest payment transaction for a payment.
     *
     * @param int $paymentId
     * @return array|null
     */
    public function getLatestTransactionByPaymentId($paymentId)
    {
        return $this->where('payment_id', $paymentId)
            ->orderBy('transaction_date', 'DESC')
            ->first();
    }
}
