<?php

declare(strict_types=1);

namespace Kylin\Ecommerce\Services;

use Illuminate\Support\Facades\Cache;

/**
 * 商家实名认证服务
 *
 * 依据《电子商务法》第二十七条：
 * 电子商务平台经营者应当要求申请进入平台销售商品或者
 * 提供服务的经营者提交其身份、地址、联系方式、行政许可等真实信息。
 *
 * 依据《网络安全法》第二十四条：
 * 用户提供真实身份信息。
 *
 * 认证项：
 *  - 企业：营业执照、法人身份证、企业对公账户
 *  - 个人：身份证正反面、手持身份证照片
 *
 * 使用方式：
 *   $result = MerchantVerificationService::verify($merchantData);
 *   $status = MerchantVerificationService::getStatus($merchantId);
 */
final class MerchantVerificationService
{
    /**
     * 认证状态
     */
    public const STATUS_PENDING = 'pending';
    public const STATUS_VERIFIED = 'verified';
    public const STATUS_REJECTED = 'rejected';
    public const STATUS_EXPIRED = 'expired';

    /**
     * 认证类型
     */
    public const TYPE_ENTERPRISE = 'enterprise';
    public const TYPE_INDIVIDUAL = 'individual';

    /**
     * 企业认证所需字段
     */
    private const ENTERPRISE_REQUIRED_FIELDS = [
        'company_name',
        'credit_code',
        'legal_person_name',
        'legal_person_id_card',
        'business_license',
        'contact_name',
        'contact_phone',
    ];

    /**
     * 个人认证所需字段
     */
    private const INDIVIDUAL_REQUIRED_FIELDS = [
        'real_name',
        'id_card_number',
        'id_card_front',
        'id_card_back',
        'handheld_id_card',
        'contact_phone',
    ];

    /**
     * 提交认证申请
     *
     * @param array $data 认证数据
     * @param string $type 认证类型：enterprise/individual
     * @return array 认证结果
     */
    public static function submit(array $data, string $type = self::TYPE_INDIVIDUAL): array
    {
        // 验证必填字段
        $requiredFields = $type === self::TYPE_ENTERPRISE
            ? self::ENTERPRISE_REQUIRED_FIELDS
            : self::INDIVIDUAL_REQUIRED_FIELDS;

        $missing = array_diff($requiredFields, array_keys(array_filter($data)));
        if (! empty($missing)) {
            return [
                'success' => false,
                'message' => '缺少必填字段：' . implode(', ', $missing),
                'status' => self::STATUS_REJECTED,
            ];
        }

        // 身份证号格式验证
        if (! empty($data['id_card_number']) && ! self::validateIdCard($data['id_card_number'])) {
            return [
                'success' => false,
                'message' => '身份证号格式不正确',
                'status' => self::STATUS_REJECTED,
            ];
        }

        // 统一社会信用代码验证
        if ($type === self::TYPE_ENTERPRISE && ! empty($data['credit_code'])) {
            if (! self::validateCreditCode($data['credit_code'])) {
                return [
                    'success' => false,
                    'message' => '统一社会信用代码格式不正确',
                    'status' => self::STATUS_REJECTED,
                ];
            }
        }

        return [
            'success' => true,
            'message' => '认证申请已提交，请等待审核',
            'status' => self::STATUS_PENDING,
            'type' => $type,
            'submitted_at' => now()->toDateTimeString(),
            'law' => '《电子商务法》第二十七条',
        ];
    }

    /**
     * 获取认证状态
     *
     * @param int $merchantId 商家 ID
     * @return string 认证状态
     */
    public static function getStatus(int $merchantId): string
    {
        return Cache::get("merchant:verification:{$merchantId}", self::STATUS_PENDING);
    }

    /**
     * 更新认证状态
     *
     * @param int $merchantId 商家 ID
     * @param string $status 认证状态
     * @param string|null $remark 审核备注
     */
    public static function updateStatus(int $merchantId, string $status, ?string $remark = null): void
    {
        $validStatuses = [self::STATUS_PENDING, self::STATUS_VERIFIED, self::STATUS_REJECTED, self::STATUS_EXPIRED];
        if (! in_array($status, $validStatuses, true)) {
            throw new \InvalidArgumentException("无效的认证状态：{$status}");
        }

        Cache::put("merchant:verification:{$merchantId}", $status, now()->addYear());

        logger()->info('商家认证状态更新', [
            'merchant_id' => $merchantId,
            'status' => $status,
            'remark' => $remark,
            'operator' => auth()->user()?->name ?? '系统',
            'operator_id' => auth()->id() ?? 0,
            'timestamp' => now()->toDateTimeString(),
        ]);
    }

    /**
     * 检查商家是否已认证
     *
     * @param int $merchantId 商家 ID
     * @return bool
     */
    public static function isVerified(int $merchantId): bool
    {
        return self::getStatus($merchantId) === self::STATUS_VERIFIED;
    }

    /**
     * 检查商家是否可以入驻
     */
    public static function canSettle(int $merchantId): bool
    {
        $status = self::getStatus($merchantId);
        return in_array($status, [self::STATUS_VERIFIED, self::STATUS_PENDING], true);
    }

    /**
     * 验证身份证号格式
     *
     * @param string $idCard 身份证号
     * @return bool
     */
    public static function validateIdCard(string $idCard): bool
    {
        // 18位身份证号正则
        $pattern = '/^\d{17}[\dXx]$/';
        if (! preg_match($pattern, $idCard)) {
            return false;
        }

        // 校验码验证
        $weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        $checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

        $sum = 0;
        for ($i = 0; $i < 17; $i++) {
            $sum += (int) $idCard[$i] * $weights[$i];
        }

        $checkCode = $checkCodes[$sum % 11];

        return strtoupper($idCard[17]) === $checkCode;
    }

    /**
     * 验证统一社会信用代码格式
     *
     * @param string $creditCode 统一社会信用代码
     * @return bool
     */
    public static function validateCreditCode(string $creditCode): bool
    {
        // 18位：数字+大写字母
        $pattern = '/^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/';
        return (bool) preg_match($pattern, $creditCode);
    }

    /**
     * 合规声明
     */
    public static function complianceNotice(): string
    {
        return '本商家实名认证系统遵循《电子商务法》第二十七条和《网络安全法》第二十四条。';
    }
}