<?php
declare (strict_types = 1);

namespace app\admin\controller\api;

use think\admin\Controller;
use think\facade\Db;

/**
 * Cursor账号管理接口
 */
class Account extends Controller
{
    /**
     * 添加账号
     */
    public function add()
    {
        try {
            $data = $this->_vali([
                'email.require' => '邮箱不能为空',
                'password.require' => '密码不能为空',
                'first_name.require' => '名字不能为空',
                'last_name.require' => '姓氏不能为空',
                'access_token.require' => 'access_token不能为空',
                'refresh_token.require' => 'refresh_token不能为空',
                'registration_time.require' => '注册时间不能为空'
            ]);

            // 检查邮箱是否已存在
            if (Db::name('cursor_accounts')->where('email', $data['email'])->find()) {
                return json([
                    'code' => 400,
                    'msg' => '该邮箱已存在'
                ]);
            }

            // 准备插入数据
            $insertData = [
                'email' => $data['email'],
                'password' => $data['password'],
                'first_name' => $data['first_name'],
                'last_name' => $data['last_name'],
                'access_token' => $data['access_token'],
                'refresh_token' => $data['refresh_token'],
                'machine_id' => $data['machine_id'] ?? '',
                'user_agent' => $data['user_agent'] ?? '',
                'registration_time' => $data['registration_time'],
                'created_at' => date('Y-m-d H:i:s'),
                'is_used' => 0
            ];

            // 插入数据
            $id = Db::name('cursor_accounts')->insertGetId($insertData);

            return json([
                'code' => 200,
                'msg' => '添加成功',
                'data' => ['id' => $id]
            ]);

        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
    }

    /**
     * 获取未使用的账号
     */
    public function getUnused()
    {
        try {
            // 获取machine_id
            $machineId = input('machine_id', '');
            if (empty($machineId)) {
                return json([
                    'code' => 401,
                    'msg' => '设备ID不能为空'
                ]);
            }

            // 优先检查缓存中是否有该设备最近使用的账号
            $cacheKey = "device_account_{$machineId}";
            $cachedAccount = \think\facade\Cache::get($cacheKey);
            
            if ($cachedAccount) {
                // 检查账号是否仍然可用
                $account = Db::name('cursor_accounts')
                    ->where('id', $cachedAccount['id'])
                    ->find();
                    
                if ($account) {
                    // 更新缓存时间
                    \think\facade\Cache::set($cacheKey, $account, 600); // 10分钟缓存
                    
                    // 查询设备激活状态用于计算过期时间
                    $activations = Db::name('cursor_activation_codes')
                        ->where('used_by', '=', $machineId)
                        ->where('is_used', '=', 1)
                        ->order('used_at desc')
                        ->select()
                        ->toArray();

                    if (!empty($activations)) {
                        $totalDays = array_sum(array_column($activations, 'days'));
                        $firstActivationTime = strtotime($activations[count($activations)-1]['used_at']);
                        $expireTime = $firstActivationTime + ($totalDays * 24 * 3600);
                        
                        // 返回账号信息
                        return json([
                            'code' => 200,
                            'msg' => '获取成功',
                            'data' => [
                                'email' => $account['email'],
                                'password' => $account['password'],
                                'access_token' => $account['access_token'],
                                'refresh_token' => $account['refresh_token'],
                                'expire_time' => date('Y-m-d H:i:s', $expireTime),
                                'days_left' => ceil(($expireTime - time()) / 86400)
                            ]
                        ]);
                    }
                }
            }

            // 查询设备激活状态
            $activations = Db::name('cursor_activation_codes')
                ->where('used_by', '=', $machineId)
                ->where('is_used', '=', 1)
                ->order('used_at desc')
                ->select()
                ->toArray();

            if (empty($activations)) {
                return json([
                    'code' => 401,
                    'msg' => '设备未激活'
                ]);
            }

            // 计算总天数和到期时间
            $totalDays = array_sum(array_column($activations, 'days'));
            $firstActivationTime = strtotime($activations[count($activations)-1]['used_at']);
            $expireTime = $firstActivationTime + ($totalDays * 24 * 3600);
            
            // 检查是否过期
            if (time() > $expireTime) {
                return json([
                    'code' => 401,
                    'msg' => '设备授权已过期'
                ]);
            }

            // 在分配新账号前检查冷却期
            $cooldownKey = "device_cooldown_{$machineId}";
            $isInCooldown = \think\facade\Cache::get($cooldownKey);
            if ($isInCooldown) {
                return json([
                    'code' => 429,
                    'msg' => '请求过于频繁，请稍后再试',
                    'data' => [
                        'cooldown_expires' => date('Y-m-d H:i:s', intval($isInCooldown))
                    ]
                ]);
            }

            // 开启事务
            Db::startTrans();
            try {
                // 获取一个未使用的账号
                $account = Db::name('cursor_accounts')
                    ->where('is_used', 0)
                    ->lock(true)
                    ->find();

                if (empty($account)) {
                    Db::rollback();
                    return json([
                        'code' => 404,
                        'msg' => '没有可用的账号'
                    ]);
                }

                // 如果有旧账号，将其标记为未使用
                if ($cachedAccount) {
                    Db::name('cursor_accounts')
                        ->where('id', $cachedAccount['id'])
                        ->update([
                            'is_used' => 0,
                            'used_at' => null,
                            'used_by' => ''
                        ]);
                }

                // 更新新账号状态
                Db::name('cursor_accounts')
                    ->where('id', $account['id'])
                    ->update([
                        'is_used' => 1,
                        'used_at' => date('Y-m-d H:i:s'),
                        'used_by' => $machineId
                    ]);

                // 设置冷却期（仅在成功分配新账号时）
                $cooldownExpires = time() + 1800; // 30分钟冷却期
                \think\facade\Cache::set($cooldownKey, $cooldownExpires, 1800);

                Db::commit();

                // 缓存新账号信息
                \think\facade\Cache::set($cacheKey, $account, 600); // 10分钟缓存

                // 返回账号信息
                return json([
                    'code' => 200,
                    'msg' => '获取成功',
                    'data' => [
                        'email' => $account['email'],
                        'password' => $account['password'],
                        'access_token' => $account['access_token'],
                        'refresh_token' => $account['refresh_token'],
                        'expire_time' => date('Y-m-d H:i:s', $expireTime),
                        'days_left' => ceil(($expireTime - time()) / 86400)
                    ]
                ]);

            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }

        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
    }

    /**
     * 后台强制重置设备账号
     * @auth true
     */
    public function resetDeviceAccount()
    {
        try {
            $data = $this->_vali([
                'machine_id.require' => '设备ID不能为空'
            ]);

            $machineId = $data['machine_id'];

            // 清除设备的账号缓存
            $cacheKey = "device_account_{$machineId}";
            \think\facade\Cache::delete($cacheKey);

            // 清除冷却期
            $cooldownKey = "device_cooldown_{$machineId}";
            \think\facade\Cache::delete($cooldownKey);

            // 将该设备使用的账号标记为未使用
            Db::name('cursor_accounts')
                ->where('used_by', $machineId)
                ->update([
                    'is_used' => 0,
                    'used_at' => null,
                    'used_by' => ''
                ]);

            return json([
                'code' => 200,
                'msg' => '重置成功'
            ]);

        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
    }
}
