<?php

declare(strict_types=1);

namespace Kylin\Pay\Shortcut\Wechat;

use Kylin\Pay\Artful\Contract\ShortcutInterface;
use Kylin\Pay\Artful\Exception\InvalidParamsException;
use Kylin\Pay\Artful\Plugin\AddPayloadBodyPlugin;
use Kylin\Pay\Artful\Plugin\ParserPlugin;
use Kylin\Pay\Artful\Plugin\StartPlugin;
use Kylin\Pay\Exception\Exception;
use Kylin\Pay\Plugin\Wechat\AddRadarPlugin;
use Kylin\Pay\Plugin\Wechat\ResponsePlugin;
use Kylin\Pay\Plugin\Wechat\V2\AddPayloadSignaturePlugin;
use Kylin\Pay\Plugin\Wechat\V2\Papay\Direct\ApplyPlugin;
use Kylin\Pay\Plugin\Wechat\V2\Papay\Direct\ContractOrderPlugin;
use Kylin\Pay\Plugin\Wechat\V2\Papay\Direct\MiniOnlyContractPlugin;
use Kylin\Pay\Plugin\Wechat\V2\Pay\App\InvokePlugin as AppInvokePlugin;
use Kylin\Pay\Plugin\Wechat\V2\Pay\Mini\InvokePlugin as MiniInvokePlugin;
use Kylin\Pay\Plugin\Wechat\V2\VerifySignaturePlugin;
use Kylin\Pay\Supports\Str;

class PapayShortcut implements ShortcutInterface
{
    /**
     * @throws InvalidParamsException
     */
    public function getPlugins(array $params): array
    {
        $method = Str::camel($params['_action'] ?? 'default').'Plugins';

        if (method_exists($this, $method)) {
            return $this->{$method}($params);
        }

        throw new InvalidParamsException(Exception::PARAMS_SHORTCUT_ACTION_INVALID, "您所提供的 action 方法 [{$method}] 不支持，请参考文档或源码确认");
    }

    /**
     * @throws InvalidParamsException
     */
    protected function defaultPlugins(array $params): array
    {
        return $this->orderPlugins($params);
    }

    /**
     * @throws InvalidParamsException
     */
    protected function orderPlugins(array $params): array
    {
        return [
            StartPlugin::class,
            ContractOrderPlugin::class,
            AddPayloadSignaturePlugin::class,
            AddPayloadBodyPlugin::class,
            AddRadarPlugin::class,
            $this->getInvoke($params),
            VerifySignaturePlugin::class,
            ResponsePlugin::class,
            ParserPlugin::class,
        ];
    }

    /**
     * @throws InvalidParamsException
     */
    protected function contractPlugins(array $params): array
    {
        return match ($params['_type'] ?? 'default') {
            'mini' => [StartPlugin::class, MiniOnlyContractPlugin::class, AddPayloadSignaturePlugin::class],
            default => throw new InvalidParamsException(Exception::PARAMS_WECHAT_PAPAY_TYPE_NOT_SUPPORTED, '参数异常: 微信扣关服务纯签约，当前传递的 `_type` 类型不支持')
        };
    }

    protected function applyPlugins(): array
    {
        return [
            StartPlugin::class,
            ApplyPlugin::class,
            AddPayloadSignaturePlugin::class,
            AddPayloadBodyPlugin::class,
            AddRadarPlugin::class,
            VerifySignaturePlugin::class,
            ResponsePlugin::class,
            ParserPlugin::class,
        ];
    }

    /**
     * @throws InvalidParamsException
     */
    protected function getInvoke(array $params): string
    {
        return match ($params['_type'] ?? 'default') {
            'app' => AppInvokePlugin::class,
            'mini' => MiniInvokePlugin::class,
            default => throw new InvalidParamsException(Exception::PARAMS_WECHAT_PAPAY_TYPE_NOT_SUPPORTED, '参数异常: 微信扣关服务支付中签约，当前传递的 `_type` 类型不支持')
        };
    }
}
