<?php

namespace App\Controllers;

use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\Writer\PngWriter;

class QrController extends BaseController
{
    public function index()
    {
        return view('qrcode'); // โหลด View ที่ชื่อว่า qrcode.php
    }

    public function generate()
{
    $data = $this->request->getPost();
    $promptPayId = $data['promptpay_id'];
    $amount = $data['amount'];

    if (empty($promptPayId) || !is_numeric($amount)) {
        return $this->response->setJSON(['error' => 'Invalid input']);
    }

    // สร้าง Payload พร้อมเพย์
    $payload = $this->generatePromptPayPayload($promptPayId, $amount);

    // สร้าง QR Code
    $result = Builder::create()
        ->writer(new PngWriter())
        ->data($payload)
        ->encoding(new Encoding('UTF-8'))
        ->build();

    // ส่งคืน QR Code เป็น Base64
    $qrImage = base64_encode($result->getString());

    return $this->response->setJSON(['qr_image' => $qrImage]);
}


    private function generatePromptPayPayload($id, $amount)
{
    // ตรวจสอบ ID ว่าเป็นเบอร์โทรหรือเลขประจำตัวประชาชน
    $type = strlen($id) === 10 ? '01' : '02'; // 01 = เบอร์โทร, 02 = เลขบัตรประชาชน
    $id = preg_replace('/[^0-9]/', '', $id); // เอาเฉพาะตัวเลข
    
    if ($type === '01') {
        $id = "0066" . substr($id, 1); // แปลงเบอร์โทรเป็นรหัสประเทศ
    }

    // ข้อมูล Payload
    $payload = [
        '00' => '01',                  // เวอร์ชัน
        '01' => '11',                  // Static QR
        '29' => [                      // ข้อมูลพร้อมเพย์
            '00' => 'A000000677010111', // Merchant Account PromptPay
            '01' => $type . $id         // PromptPay ID
        ],
        '58' => 'TH',                  // ประเทศ
        '53' => '764',                 // สกุลเงิน (บาท)
        '54' => sprintf('%.2f', $amount), // จำนวนเงินในรูปแบบ 2 ทศนิยม
        '63' => ''                     // CRC (เติมภายหลัง)
    ];

    // สร้าง Payload เป็นสตริง
    $payloadString = $this->buildPayload($payload);

    // คำนวณ CRC16 และเติมในฟิลด์ 63
    $crc = strtoupper($this->calculateCRC16($payloadString . '6304'));
    return $payloadString . '6304' . $crc;
}

private function buildPayload($data)
{
    $result = '';
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            $subPayload = $this->buildPayload($value);
            $result .= sprintf('%02d%02d%s', $key, strlen($subPayload), $subPayload);
        } else {
            $result .= sprintf('%02d%02d%s', $key, strlen($value), $value);
        }
    }
    return $result;
}

private function calculateCRC16($input)
{
    $polynomial = 0x1021; // CRC16-CCITT
    $crc = 0xFFFF;

    for ($i = 0; $i < strlen($input); $i++) {
        $crc ^= (ord($input[$i]) << 8);
        for ($j = 0; $j < 8; $j++) {
            if ($crc & 0x8000) {
                $crc = ($crc << 1) ^ $polynomial;
            } else {
                $crc = $crc << 1;
            }
        }
    }

    return str_pad(dechex($crc & 0xFFFF), 4, '0', STR_PAD_LEFT);
}

}
