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

class Payhalal extends App_Controller
{
    public function callback()
    {
      
        $method = $this->input->method(true);

        // ---------- GET PHASE: browser return with only order ids -> redirect to invoice ----------
        if ($method === 'GET') {
            $orderId = $this->input->get('order_id') ?: $this->input->get('customer_order_id');
            // log_activity('PayHalal CALLBACK DEBUG (GET): '.json_encode([
            //     'payload' => $this->input->get(NULL, false)
            // ]));

            if (!$orderId) {
                show_error('Missing order_id', 400);
            }

            $invoice = $this->findInvoiceByFormattedNumber($orderId);
            if (!$invoice) {
                log_activity('PayHalal GET: invoice not found for order_id '.$orderId);
                show_404();
            }

            // Read & clear the one-shot alert
    $flag = get_option('ph_alert_' . $orderId);
    if ($flag) {
        $f = json_decode($flag, true);
        if (isset($f['s']) && $f['s'] === 'success') {
            set_alert('success', _l('online_payment_recorded_success'));
        } else {
            set_alert('danger', _l('online_payment_recorded_fail'));
        }
        delete_option('ph_alert_' . $orderId);
    }

            // Public invoice URL needs id + hash
            redirect(site_url('invoice/'.$invoice->id.'/'.$invoice->hash));
            return;
        }

        // ---------- POST PHASE: full payload (store payment) ----------
        // Accept multipart/form-data | x-www-form-urlencoded | raw JSON | raw querystring
        $requestData = json_encode($_REQUEST);
        $payload = json_decode($requestData, true);
        if (empty($payload)) {
            $raw = file_get_contents('php://input');
            $json = json_decode($raw, true);
            if (is_array($json) && !empty($json)) {
                $payload = $json;
            } elseif (!empty($raw)) {
                $qs = [];
                parse_str($raw, $qs);
                if (!empty($qs)) $payload = $qs;
            }
        }
        if (empty($payload) && !empty($_REQUEST)) {
            $payload = $_REQUEST;
        }

        // Clean odd key PayHalal sends (e.g. "/gateways/payhalal/callback": "")
        foreach (array_keys($payload) as $k) {
            if (strpos($k, '/gateways/payhalal/callback') !== false) {
                unset($payload[$k]);
            }
        }

        // log_activity('PayHalal CALLBACK DEBUG (POST): ' . json_encode([
        //     'content_type' => $this->input->get_request_header('Content-Type', true),
        //     'payload'      => $payload,
        // ]));

        $status    = $payload['status']          ?? null;  // "SUCCESS"
        $orderId   = $payload['order_id']        ?? null;  // MUZK26000001
        $txnId     = $payload['transaction_id']  ?? null;
        $amountStr = $payload['amount']          ?? null;  // "1,000.00" or "1000.00"
        $currency  = $payload['currency']        ?? null;
        $cName     = $payload['customer_name']   ?? '';
        $cEmail    = $payload['customer_email']  ?? '';
        $cPhone    = $payload['customer_phone']  ?? '';
        $recvHash  = $payload['hash']            ?? null;

        if (!$status || !$orderId || !$txnId || !$amountStr || !$currency) {
            log_activity('PayHalal BAD PAYLOAD: ' . json_encode($payload));
            show_error('Bad callback payload', 400);
        }

        // Normalize amount
        $amountStrNorm = str_replace(',', '', trim($amountStr));
        if (!is_numeric($amountStrNorm) || (float)$amountStrNorm <= 0) {
            log_activity('PayHalal invalid amount: '.$amountStr);
            show_error('Invalid amount', 400);
        }
        $amount = (float)$amountStrNorm;

        // Find the invoice (MUZK26 + 000001)
        $invoice = $this->findInvoiceByFormattedNumber($orderId);
        if (!$invoice) {
            log_activity('PayHalal: invoice not found for order_id '.$orderId);
            show_error('Invoice not found', 404);
        }

        // Rebuild description exactly as in process_payment()
        $descTpl = $this->payhalal_gateway->getSetting('description_dashboard'); // "Payment for Invoice {invoice_number}"
        $desc    = str_replace('{invoice_number}', format_invoice_number($invoice->id), $descTpl);

        // Verify hash: sha256(secret . amount . currency . description . order_id . name . email . phone)
        $secret      = $this->payhalal_gateway->decryptSetting('secretkey');
        $expectedHash = hash('sha256', $secret.$amountStrNorm.$currency.$desc.$orderId.$cName.$cEmail.$cPhone);

        // if (!$recvHash || !hash_equals($expectedHash, $recvHash)) {
        //     log_activity('PayHalal HASH MISMATCH: expected='.$expectedHash.' received='.$recvHash.' order='.$orderId);
        //     show_error('Hash mismatch', 400);
        // }

        // Idempotency
        $exists = total_rows(db_prefix().'invoicepaymentrecords', ['transactionid' => $txnId]) > 0;
        if ($exists) { echo 'OK'; return; }

        if (strtoupper($status) === 'SUCCESS') {
            $ok = $this->payhalal_gateway->addPayment([
                'amount'        => $amount,
                'invoiceid'     => $invoice->id,
                'transactionid' => $txnId,
            ]);
            if ($ok) {
                update_option('ph_alert_' . $orderId, json_encode(['s' => 'success', 't' => time()]));
                echo 'OK'; // important: 200 OK for PayHalal server
            } else {
                update_option('ph_alert_' . $orderId, json_encode(['s' => 'fail', 't' => time()]));
                log_activity('PayHalal addPayment failed for invoice ' . $invoice->id);
                show_error('Failed to record payment', 500);
            }
        }else {
    update_option('ph_alert_' . $orderId, json_encode(['s' => 'fail', 't' => time()]));
    echo 'IGNORED';
}
    }

    /**
     * Helper: find invoice by formatted number like "MUZK26000001"
     */
    private function findInvoiceByFormattedNumber(string $formatted)
    {
        // Split prefix + numeric tail
        if (preg_match('/^(.+?)(\d+)$/', $formatted, $m)) {
            $prefix = $m[1];
            $numInt = (int)$m[2];

            $inv = $this->db->where('prefix', $prefix)
                            ->where('number', $numInt)
                            ->get(db_prefix().'invoices')->row();
            if ($inv) return $inv;
        }
        // Fallback: try CONCAT with 6-digit padding
        return $this->db
            ->where('CONCAT(prefix, LPAD(number, 6, "0")) =', $formatted)
            ->get(db_prefix().'invoices')->row();
    }
}
