<?php
/**
 * Chupito SaaS — Checkout & TatraPay Integration
 * /var/www/html/chupito-saas/checkout.php
 */
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }

define('SAAS_DB_HOST', 'localhost');
define('SAAS_DB_NAME', 'chupito_saas');
define('SAAS_DB_USER', 'chupito_saas');
define('SAAS_DB_PASS', 'SaaS2026x!');

define('TATRAPAY_TOKEN_URL', 'https://api.tatrabanka.sk/tatrapayplus/sandbox/auth/oauth/v2/token');
define('TATRAPAY_API_URL',   'https://api.tatrabanka.sk/tatrapayplus/sandbox');
define('TATRAPAY_CLIENT_ID', 'l7ca39b0778f8f47ab9363662c364d4c3f');
define('TATRAPAY_SECRET',    'a08f1c27a353458181161d35de3aa5d8');
define('REDIRECT_URI',       'https://chupito.sk/payment/callback');
define('BASE_DOMAIN',        'reserve.chupito.sk');

define('PRICE_MONTHLY', 40.00);
define('PRICE_YEARLY',  360.00);

function db(): PDO {
    static $pdo;
    if (!$pdo) $pdo = new PDO(
        'mysql:host='.SAAS_DB_HOST.';dbname='.SAAS_DB_NAME.';charset=utf8mb4',
        SAAS_DB_USER, SAAS_DB_PASS,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
    return $pdo;
}

function ok($data=[]) { echo json_encode(['success'=>true]+$data); exit; }
function err($msg, $code=400) { http_response_code($code); echo json_encode(['success'=>false,'error'=>$msg]); exit; }

function getTatraPayToken(): string {
    $ch = curl_init(TATRAPAY_TOKEN_URL);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query([
            'grant_type'    => 'client_credentials',
            'client_id'     => TATRAPAY_CLIENT_ID,
            'client_secret' => TATRAPAY_SECRET,
            'scope'         => 'TATRAPAYPLUS',
        ]),
        CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_TIMEOUT => 15,
    ]);
    $resp = curl_exec($ch);
    curl_close($ch);
    $data = json_decode($resp, true);
    if (empty($data['access_token'])) {
        throw new Exception('TatraPay token failed: ' . $resp);
    }
    return $data['access_token'];
}

function generateSlug(string $name): string {
    $slug = strtolower($name);
    $slug = iconv('UTF-8', 'ASCII//TRANSLIT', $slug);
    $slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
    $slug = trim($slug, '-');
    $slug = substr($slug, 0, 30);
    // Check uniqueness
    $base = $slug;
    $i = 1;
    while (db()->prepare("SELECT id FROM customers WHERE slug=?")->execute([$slug]) &&
           db()->prepare("SELECT id FROM customers WHERE slug=?")->execute([$slug]) &&
           db()->query("SELECT COUNT(*) FROM customers WHERE slug='$slug'")->fetchColumn() > 0) {
        $slug = $base . '-' . $i++;
    }
    return $slug;
}

function generatePassword(): string {
    return substr(str_shuffle('ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789'), 0, 4)
         . substr(str_shuffle('0123456789'), 0, 4)
         . substr(str_shuffle('!@#$'), 0, 2);
}

$action = $_GET['action'] ?? $_POST['action'] ?? '';
$input  = json_decode(file_get_contents('php://input'), true) ?: [];

switch ($action) {

    // ── Create checkout session ───────────────────────────────────────────
    case 'create_checkout':
        $required = ['restaurant_name','contact_name','email','phone','plan'];
        foreach ($required as $f) {
            if (empty($input[$f])) err("Chýba pole: $f");
        }

        $plan   = $input['plan'] === 'yearly' ? 'yearly' : 'monthly';
        $amount = $plan === 'yearly' ? PRICE_YEARLY : PRICE_MONTHLY;

        // Generate slug + credentials
        $slug      = generateSlug($input['restaurant_name']);
        $subdomain = $slug . '.' . BASE_DOMAIN;
        $dbName    = preg_replace('/[^a-z0-9_]/', '_', 'cr_' . $slug);
        $dbUser    = substr($dbName, 0, 32);
        $dbPass    = 'R' . bin2hex(random_bytes(8)) . '!';
        $apiKey    = bin2hex(random_bytes(16));
        $adminPass = generatePassword();

        // Check if email already exists
        $db = db();
        $existing = $db->prepare('SELECT id, status FROM customers WHERE email=?');
        $existing->execute([$input['email']]);
        $existingRow = $existing->fetch();
        if ($existingRow) {
            if ($existingRow['status'] === 'active') err('Tento email je už zaregistrovaný. Prihláste sa do svojej administrácie alebo kontaktujte info@chupito.sk');
            else { $db->prepare('DELETE FROM customers WHERE email=?')->execute([$input['email']]); $db->prepare('DELETE FROM payments WHERE customer_id=?')->execute([$existingRow['id']]); }
        }
        $db->prepare("INSERT INTO customers 
            (restaurant_name,contact_name,email,phone,ico,address,slug,subdomain,db_name,db_user,db_pass,api_key,admin_email,admin_pass,plan,status)
            VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,'$plan','pending')")
            ->execute([
                $input['restaurant_name'],
                $input['contact_name'],
                $input['email'],
                $input['phone'],
                $input['ico'] ?? null,
                $input['address'] ?? null,
                $slug, $subdomain, $dbName, $dbUser, $dbPass,
                $apiKey,
                $input['email'],
                $adminPass,
            ]);
        $customerId = $db->lastInsertId();

        // Initiate TatraPay payment
        try {
            $token = getTatraPayToken();
            $requestId = bin2hex(random_bytes(16));

            $nameParts = explode(' ', trim($input['contact_name']));
            $firstName = $nameParts[0];
            $lastName  = count($nameParts) > 1 ? implode(' ', array_slice($nameParts, 1)) : $firstName;
            $paymentBody = [
                'basePayment' => [
                    'instructedAmount' => [
                        'amountValue' => $amount,
                        'currency'    => 'EUR',
                    ],
                    'endToEnd' => 'CHUPITO-' . $customerId . '-' . time(),
                ],
                'userData' => [
                    'email'     => $input['email'],
                    'firstName' => $firstName,
                    'lastName'  => $lastName,
                ],
                'cardDetail' => [
                    'cardHolder' => $firstName . ' ' . $lastName,
                ],
                'bankTransfer' => (object)[],
            ];

            $ch = curl_init(TATRAPAY_API_URL . '/v1/payments');
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POST           => true,
                CURLOPT_POSTFIELDS     => json_encode($paymentBody),
                CURLOPT_HTTPHEADER     => [
                    'Content-Type: application/json',
                    'Authorization: Bearer ' . $token,
                    'X-Request-ID: ' . $requestId,
                    'IP-Address: 178.104.34.112',
                    'Redirect-URI: ' . REDIRECT_URI . '?customer_id=' . $customerId,
                ],
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_TIMEOUT => 15,
            ]);
            $resp = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            $payResp = json_decode($resp, true);

            if ($httpCode !== 201 || empty($payResp['paymentId'])) {
                throw new Exception("TatraPay error ($httpCode): $resp");
            }

            // Save payment record
            $db->prepare("INSERT INTO payments (customer_id,payment_id,amount,plan,status,tatrapay_response) VALUES (?,?,?,?,?,?)")
                ->execute([$customerId, $payResp['paymentId'], $amount, $plan, 'pending', json_encode($payResp)]);

            ok([
                'customer_id'       => $customerId,
                'payment_id'        => $payResp['paymentId'],
                'tatrapay_url'      => $payResp['tatraPayPlusUrl'],
                'amount'            => $amount,
                'plan'              => $plan,
            ]);

        } catch (Exception $e) {
            // Mark customer as failed
            $db->prepare("UPDATE customers SET status='cancelled' WHERE id=?")->execute([$customerId]);
            err('Platobná brána nedostupná: ' . $e->getMessage());
        }

    // ── Payment callback (after redirect from TatraPay) ───────────────────
    case 'payment_callback':
        $paymentId  = $input['paymentId']   ?? $_GET['paymentId']   ?? '';
        $customerId = $input['customer_id'] ?? $_GET['customer_id'] ?? 0;
        if (!$paymentId || !$customerId) err('Chýbajú parametre');

        // Get payment status from TatraPay
        try {
            $token = getTatraPayToken();
            $ch = curl_init(TATRAPAY_API_URL . '/v1/payments/' . $paymentId . '/status');
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HTTPHEADER     => [
                    'Authorization: Bearer ' . $token,
                    'X-Request-ID: ' . bin2hex(random_bytes(8)),
                ],
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_TIMEOUT => 15,
            ]);
            $resp = curl_exec($ch);
            curl_close($ch);
            $status = json_decode($resp, true);
        } catch (Exception $e) {
            err('Status check failed: ' . $e->getMessage());
        }

        // Check if payment OK
        $authStatus = $status['authorizationStatus'] ?? '';
        $payStatus  = $status['status']['status']    ?? '';

        // Retry up to 5x if still processing
        $retries = 0;
        while (in_array($authStatus, ['NEW','PAY_METHOD_SELECTED']) && $retries < 5) {
            sleep(2);
            try {
                $token2 = getTatraPayToken();
                $ch2 = curl_init(TATRAPAY_API_URL . '/v1/payments/' . $paymentId . '/status');
                curl_setopt_array($ch2, [
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $token2, 'X-Request-ID: ' . bin2hex(random_bytes(8))],
                    CURLOPT_SSL_VERIFYPEER => false,
                    CURLOPT_TIMEOUT => 10,
                ]);
                $resp2 = curl_exec($ch2); curl_close($ch2);
                $status = json_decode($resp2, true);
                $authStatus = $status['authorizationStatus'] ?? '';
                $payStatus  = $status['status']['status']    ?? '';
            } catch (Exception $e) {}
            $retries++;
        }

        $db = db();
        $db->prepare("UPDATE payments SET status=?, tatrapay_response=? WHERE payment_id=?")
            ->execute([($payStatus === 'OK') ? 'ok' : 'fail', json_encode($status), $paymentId]);

        if ($payStatus === 'OK' || $authStatus === 'AUTH_DONE') {
            exec("php /var/www/html/chupito-saas/provision.php $customerId > /var/log/provision_$customerId.log 2>&1 &");
            ok(['status' => 'ok', 'customer_id' => $customerId, 'message' => 'Provisioning started']);
        } elseif (in_array($authStatus, ['NEW','PAY_METHOD_SELECTED','AUTH_REQUIRED'])) {
            ok(['status' => 'pending', 'auth_status' => $authStatus, 'pay_status' => $payStatus, 'customer_id' => $customerId]);
        } else {
            $db->prepare("UPDATE customers SET status='cancelled' WHERE id=?")->execute([$customerId]);
            ok(['status' => 'fail', 'auth_status' => $authStatus, 'pay_status' => $payStatus]);
        }

    // ── Check provisioning status ─────────────────────────────────────────
    case 'check_status':
        $customerId = (int)($input['customer_id'] ?? $_GET['customer_id'] ?? 0);
        if (!$customerId) err('Chýba customer_id');
        $stmt = db()->prepare("SELECT status, subdomain, admin_email FROM customers WHERE id=?");
        $stmt->execute([$customerId]);
        $c = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$c) err('Zákazník nenájdený');
        ok(['customer_status' => $c['status'], 'subdomain' => $c['subdomain'], 'email' => $c['admin_email']]);

    default:
        err('Neznáma akcia');
}
