<?php

declare(strict_types=1);

namespace Kylin\Education\Services;

/**
 * 监护人同意服务
 *
 * 依据《中华人民共和国未成年人保护法》(2021.6.1 修订)：
 * - 第七十二条：处理不满十四周岁未成年人个人信息的，
 *   应当取得未成年人的父母或者其他监护人的同意
 *
 * 依据《个人信息保护法》第十四条：
 * 基于个人同意处理个人信息的，该同意应当由个人在充分知情的前提下
 * 自愿、明确作出
 *
 * 使用方式：
 *   $result = GuardianConsentService::requestConsent($studentId, $guardianData);
 *   $result = GuardianConsentService::checkConsent($studentId);
 *   $result = GuardianConsentService::revokeConsent($studentId);
 */
final class GuardianConsentService
{
    /**
     * 同意状态
     */
    public const STATUS_PENDING = 'pending';       // 待同意
    public const STATUS_GRANTED = 'granted';       // 已同意
    public const STATUS_REVOKED = 'revoked';       // 已撤销
    public const STATUS_EXPIRED = 'expired';       // 已过期

    /**
     * 监护人关系
     */
    public const RELATION_FATHER = 'father';
    public const RELATION_MOTHER = 'mother';
    public const RELATION_GUARDIAN = 'guardian';
    public const RELATION_OTHER = 'other';

    /**
     * 请求监护人同意
     *
     * @param int|string $studentId 学生 ID
     * @param array $guardianData 监护人信息（含 name, phone, relation, id_card）
     * @return array{success: bool, consent_id: string, status: string, law: string}
     */
    public static function requestConsent(int|string $studentId, array $guardianData): array
    {
        // 验证监护人信息完整性
        $requiredFields = ['name', 'phone', 'relation', 'id_card'];
        $missing = array_diff($requiredFields, array_keys(array_filter($guardianData)));

        if (! empty($missing)) {
            return [
                'success' => false,
                'message' => '监护人信息不完整，缺少：' . implode(', ', $missing),
                'status' => self::STATUS_PENDING,
                'law' => '《未成年人保护法》第七十二条',
            ];
        }

        // 验证监护人关系
        $validRelations = [
            self::RELATION_FATHER,
            self::RELATION_MOTHER,
            self::RELATION_GUARDIAN,
            self::RELATION_OTHER,
        ];
        if (! in_array($guardianData['relation'], $validRelations, true)) {
            return [
                'success' => false,
                'message' => '无效的监护人关系',
                'status' => self::STATUS_PENDING,
                'law' => '《未成年人保护法》第七十二条',
            ];
        }

        // 验证监护人手机号
        if (! preg_match('/^1[3-9]\d{9}$/', $guardianData['phone'])) {
            return [
                'success' => false,
                'message' => '监护人手机号格式不正确',
                'status' => self::STATUS_PENDING,
                'law' => '《未成年人保护法》第七十二条',
            ];
        }

        // 生成同意记录 ID
        $consentId = hash('sha256', $studentId . $guardianData['id_card'] . now()->timestamp);

        // 存储同意请求（实际业务中应写入数据库）
        $consentRecord = [
            'consent_id' => $consentId,
            'student_id' => $studentId,
            'guardian_name' => $guardianData['name'],
            'guardian_phone' => self::maskPhone($guardianData['phone']),
            'guardian_relation' => $guardianData['relation'],
            'status' => self::STATUS_PENDING,
            'requested_at' => now()->toIso8601String(),
            'expires_at' => now()->addDays(30)->toIso8601String(),
        ];

        return [
            'success' => true,
            'consent_id' => $consentId,
            'status' => self::STATUS_PENDING,
            'message' => '监护人同意请求已发送，请在 30 天内完成确认',
            'law' => '《未成年人保护法》第七十二条、《个人信息保护法》第十四条',
        ];
    }

    /**
     * 检查是否已获得监护人同意
     *
     * @param int|string $studentId 学生 ID
     * @return bool
     */
    public static function checkConsent(int|string $studentId): bool
    {
        $consentRequired = config('kylin-education.student.guardian_consent_required', true);
        if (! $consentRequired) {
            return true; // 未开启监护人同意机制，默认通过
        }

        // 实际业务中应从数据库查询
        // 此处返回默认逻辑：如果配置需要监护人同意，则必须显式同意
        return false;
    }

    /**
     * 撤销监护人同意
     *
     * 依据《个人信息保护法》第十五条，个人信息处理者应当
     * 提供便捷的撤回同意的方式。
     *
     * @param int|string $studentId 学生 ID
     * @param string $reason 撤销原因
     * @return array{success: bool, status: string, law: string}
     */
    public static function revokeConsent(int|string $studentId, string $reason = ''): array
    {
        return [
            'success' => true,
            'status' => self::STATUS_REVOKED,
            'message' => '监护人同意已撤销，学员个人信息将停止处理',
            'revoked_at' => now()->toIso8601String(),
            'reason' => $reason ?: '监护人主动撤销',
            'law' => '《个人信息保护法》第十五条：个人信息处理者应当提供便捷的撤回同意的方式',
        ];
    }

    /**
     * 获取同意状态
     *
     * @param int|string $studentId 学生 ID
     * @return string
     */
    public static function getStatus(int|string $studentId): string
    {
        // 实际业务中应从数据库查询
        return self::STATUS_PENDING;
    }

    /**
     * 脱敏手机号
     *
     * @param string $phone
     * @return string
     */
    private static function maskPhone(string $phone): string
    {
        if (mb_strlen($phone) < 7) {
            return '****';
        }
        return mb_substr($phone, 0, 3) . '****' . mb_substr($phone, -4);
    }

    /**
     * 确认监护人同意
     *
     * @param string $consentId 同意记录 ID
     * @param array $verificationData 验证数据（如短信验证码等）
     * @return array{success: bool, status: string, law: string}
     */
    public static function confirmConsent(string $consentId, array $verificationData = []): array
    {
        // 实际业务中应验证短信验证码等
        return [
            'success' => true,
            'status' => self::STATUS_GRANTED,
            'message' => '监护人同意已确认',
            'confirmed_at' => now()->toIso8601String(),
            'law' => '《未成年人保护法》第七十二条、《个人信息保护法》第十四条',
        ];
    }
}