<?php

namespace App\Services;

use App\Util;
use Exception;

class AiPay
{
    protected $config;
    protected $key;
    protected $baseUrl;

    public function __construct(string $configKey = 'AiPay')
    {
        $payConfigService = new PayConfig();
        $this->config = $payConfigService->getConfig($configKey);
        $this->key = $this->config['key'] ?? '';
        $this->baseUrl = rtrim($this->config['apiUrl'] ?? 'https://api.7aipay.com', '/');
    }

    public function getConfig(): array
    {
        return $this->config;
    }

    public function sign(array $params): array
    {
        $params['sign'] = $this->generateSign($params);
        return $params;
    }

    public function verify(array $params): bool
    {
        if (!isset($params['sign'])) {
            return false;
        }
        $sign = strtoupper($params['sign']);
        unset($params['sign']);

        return $sign === $this->generateSign($params);
    }

    public function post(string $path, array $payload)
    {
        $url = $this->baseUrl . $path;
        $body = json_encode($payload, JSON_UNESCAPED_UNICODE);
        $headers = [
            'Content-Type: application/json;charset=UTF-8',
            'version: 2',
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            Util::WriteLog('AiPay_error', 'CURL Error: ' . curl_error($ch));
        }
        curl_close($ch);
        return $result;
    }

    protected function generateSign(array $params): string
    {
        $signParams = [];
        foreach ($params as $key => $value) {
            if ($key === 'sign' || $value === null || $value === '' || (is_array($value) && empty($value))) {
                continue;
            }
            if (is_array($value)) {
                $signParams[$key] = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);;
            } else {
                $signParams[$key] = $value;
            }
        }

        ksort($signParams);
        $pairs = [];
        foreach ($signParams as $key => $value) {
            $pairs[] = $key . '=' . $value;
        }
        $stringA = implode('&', $pairs);
        $stringSign = $stringA . '&key=' . $this->key;

        Util::WriteLog('AiPay', $stringSign);
        return strtoupper(md5($stringSign));
    }

    protected function buildObjectString($data): string
    {
        if (is_array($data)) {
            ksort($data);
            $parts = [];
            foreach ($data as $k => $v) {
                if ($v === null || $v === '') {
                    continue;
                }
                if (is_array($v)) {
                    $parts[] = $k . '=' . $this->buildObjectString($v);
                } else {
                    $parts[] = $k . '=' . $v;
                }
            }
            return implode('&', $parts);
        }

        return (string)$data;
    }
}

