<?php
// +----------------------------------------------------------------------
// | onezan-admin 快速开发的管理平台
// +----------------------------------------------------------------------
// | 官方网址：https://www.onezan.cn
// +----------------------------------------------------------------------
// | onezan团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: 543885307@qq.com
// +----------------------------------------------------------------------
namespace app\service\domain\pay;

use app\repository\channel\ChannelRepository;
use app\service\StorageService;
use Core\service\BaseCoreService;

/**
 * 支付配置服务
 * @package app\service\domain\pay
 */
class CorePayConfigService extends BaseCoreService
{
    /**
     * 检查渠道是否已启用
     * @param string $channel
     * @return bool
     */
    public function isChannelEnabled(string $channel): bool
    {
        $profile = $this->repository()->getProfile($channel);
        if (empty($profile)) {
            return false;
        }

        return (int)($profile['status'] ?? 0) === 1;
    }

    /**
     * 获取可用支付支付渠道
     * @param string $channel
     * @return array
     */
    public function getAvailableProviders(string $channel): array
    {
        $rows = $this->repository()->listPaymentConfigs($channel);
        $items = [];
        $providerNames = [
            'wechatpay' => '',
            'alipay' => '',
            'balance' => '',
            'offline' => '',
        ];
        $providerDescriptions = [
            'wechatpay' => '',
            'alipay' => '',
            'balance' => '',
            'offline' => '',
        ];
        foreach ($rows as $row) {
            if ((int)($row['status'] ?? 0) !== 1) {
                continue;
            }
            $key = (string)($row['provider'] ?? '');
            $items[] = [
                'key' => $key,
                'name' => $providerNames[$key] ?? $key,
                'description' => $providerDescriptions[$key] ?? '',
                'sort' => (int)($row['sort'] ?? 0),
                'config' => json_decode((string)($row['config_value'] ?? '{}'), true) ?: [],
            ];
        }

        usort($items, static function (array $a, array $b): int {
            return ((int)$a['sort']) <=> ((int)$b['sort']);
        });

        return $items;
    }

    /**
     * 获取支付渠道配置
     * @param string $channel
     * @param string $provider
     * @return array
     */
    public function getProviderConfig(string $channel, string $provider): array
    {
        foreach ($this->getAvailableProviders($channel) as $item) {
            if ((string)$item['key'] === $provider) {
                return $this->resolveProviderConfig(
                    $channel,
                    $provider,
                    is_array($item['config']) ? $item['config'] : []
                );
            }
        }

        return [];
    }

    /**
     * 解析支付渠道配置
     * @param string $channel
     * @param string $provider
     * @param array $config
     * @return array
     */
    public function resolveProviderConfig(string $channel, string $provider, array $config): array
    {
        $baseConfig = $this->repository()->getConfig($channel, 'base');

        if (trim((string)($baseConfig['app_id'] ?? '')) !== '') {
            $config['app_id'] = (string)$baseConfig['app_id'];
        }

        if ($provider === 'wechatpay') {
            $config['notify_url'] = $this->buildCallbackUrl("pay/callback/wechat/{$channel}");
            $config['refund_notify_url'] = $this->buildCallbackUrl("pay/callback/wechat/refund/{$channel}");
        }

        if ($provider === 'alipay') {
            $config['notify_url'] = $this->buildCallbackUrl("pay/callback/alipay/{$channel}");
        }

        return $config;
    }

    /**
     * 构建回调URL
     * @param string $path
     * @return string
     */
    private function buildCallbackUrl(string $path): string
    {
        return StorageService::toFullAssetUrl($this->app->request, '/api/' . ltrim($path, '/'));
    }
    /**
     * 获取渠道仓库
     * @return ChannelRepository
     */
    private function repository(): ChannelRepository
    {
        return $this->app->make(ChannelRepository::class);
    }
}
