<?php

namespace App\Models\Control;

use CodeIgniter\Model;
use Config\Lookups;

/**
 * Control DB. Payment ledger for the platform collecting subscription
 * payments FROM hotels — see CreateTransactionsTable. Mirrors
 * App\Models\PaymentAttemptModel (Phase 3, guest payments to a hotel)
 * one layer up, against the platform's own Hubtel merchant account.
 */
class TransactionModel extends Model
{
    protected $table            = 'transactions';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'object';
    protected $useTimestamps    = true;

    protected $allowedFields = [
        'tenant_id',
        'invoice_id',
        'amount',
        'type',
        'method',
        'reference',
        'client_reference',
        'status',
        'raw_response',
    ];

    public function __construct()
    {
        parent::__construct();

        $statuses = array_keys((new Lookups())->transactionStatuses);
        $types    = array_keys((new Lookups())->transactionTypes);

        $this->validationRules = [
            'tenant_id' => 'required|integer',
            'amount'    => 'required|decimal',
            'type'      => 'required|in_list[' . implode(',', $types) . ']',
            'status'    => 'required|in_list[' . implode(',', $statuses) . ']',
        ];
    }

    public function findByClientReference(string $clientReference): ?object
    {
        return $this->where('client_reference', $clientReference)->first();
    }

    /**
     * Same shape as App\Models\PaymentAttemptModel::generateClientReference
     * — unique, human-traceable, namespaced so it can never collide with a
     * tenant-level payment_attempts reference even if both systems ever
     * shared a support ticket.
     */
    public function generateClientReference(): string
    {
        return 'PLAT-' . date('YmdHis') . '-' . random_int(1000, 9999);
    }

    public function forTenant(int $tenantId): array
    {
        return $this->where('tenant_id', $tenantId)->orderBy('created_at', 'desc')->findAll();
    }

    /**
     * Joined with tenants — same reasoning as InvoiceModel::allWithTenant().
     */
    public function allWithTenant(int $limit = 200): array
    {
        return $this->select('transactions.*, tenants.hotel_name')
            ->join('tenants', 'tenants.id = transactions.tenant_id')
            ->orderBy('transactions.created_at', 'desc')
            ->limit($limit)
            ->findAll();
    }
}
