<?php
declare(strict_types=1);

namespace app\manager\controller;

use think\admin\Controller;
use think\admin\service\AdminService;


class PackageAuth extends Controller
{
    /**
     * 绑定数据表
     * @var string
     */
    protected $table = 'offer_package_auth';

    /**
     * 包名权限列表
     * @auth true
     * @menu true
     */
    public function index()
    {
        if ($this->request->isGet()) {
            // 获取所有管理员（排除超级管理员）
            $users = $this->app->db->name('system_user')
                ->where([
                    ['status', '=', 1],                    // 状态正常的用户
                    ['authorize', 'not like', '%admin%'],  // 排除admin权限组的用户
                    ['id', '<>', '10000']                 // 排除系统超管账号
                ])
                ->field('id,username,authorize')
                ->order('id asc')
                ->select()
                ->filter(function($user) {
                    // 只显示有包名管理权限的用户
                    return AdminService::instance()->check('package/index', $user['id']);
                })
                ->toArray();

            // 获取现有权限配置
            $auths = $this->app->db->name($this->table)
                ->select()
                ->toArray();

            // 整理权限数据
            $authMap = [];
            foreach ($auths as $auth) {
                $authMap[$auth['user_id']][] = $auth['package_id'];
            }

            $this->assign([
                'users' => $users,
                'authMap' => $authMap
            ]);

           $this->fetch();
        }
    }

    /**
     * 获取包名列表（分页）
     * @auth true
     */
    public function getPackageList()
    {
        if ($this->request->isPost()) {
            try {
                $page = $this->request->post('page/d', 1);
                $limit = $this->request->post('limit/d', 20);
                $keyword = $this->request->post('keyword/s', '');
                $startTime = $this->request->post('start_time/s', '');
                $endTime = $this->request->post('end_time/s', '');

                $where = [];
                // 只显示启用的包名
                $where[] = ['status', '=', 1];

                if ($keyword !== '') {
                    $where[] = ['package_name|name', 'like', "%{$keyword}%"];
                }

                // 修改时间筛选条件处理方式
                if ($startTime && $endTime) {
                    $where[] = ['add_time', 'between', [
                        strtotime($startTime),
                        strtotime($endTime)
                    ]];
                }

                // 使用正确的表名
                $query = $this->app->db->name('offer_package');

                // 先获取总数
                $total = $query->where($where)->count();

                // 获取列表数据
                $list = $query->where($where)
                    ->field('id,package_name,name,add_time,update_time,status')  // 修改字段名
                    ->order('id desc')
                    ->page($page, $limit)
                    ->select()
                    ->toArray();

                // 格式化时间戳
                foreach ($list as &$item) {
                    $item['add_time'] = date('Y-m-d H:i:s', intval($item['add_time']));
                    $item['update_time'] = date('Y-m-d H:i:s', intval($item['update_time']));
                }

                // 记录调试信息
                trace("包名列表查询：" . json_encode([
                        'where' => $where,
                        'page' => $page,
                        'limit' => $limit,
                        'total' => $total,
                        'list_count' => count($list),
                        'sql' => $query->getLastSql()
                    ], JSON_UNESCAPED_UNICODE));

                return json([
                    'code' => 0,
                    'msg' => '',
                    'count' => $total,
                    'data' => $list
                ]);
            } catch (\Exception $e) {
                // 详细记录异常信息
                trace("获取包名列表异常：" . $e->getMessage() . "\n" . $e->getTraceAsString());
                return json(['code' => 1, 'msg' => '系统异常，请稍后重试！']);
            }
        }
    }

    /**
     * 获取用户包名权限
     * @auth true
     * @api true
     */
    public function getUserAuth()
    {
        if ($this->request->isPost()) {
            try {
                $userId = $this->request->post('user_id/d', 0);
                
                if (empty($userId)) {
                    return json(['code' => 0, 'info' => '请选择管理员！']);
                }

                // 只获取包名ID列表
                $packageIds = $this->app->db->name($this->table)
                    ->where('user_id', $userId)
                    ->column('package_id');  // 直接返回ID数组

                return json([
                    'code' => 1,
                    'info' => '获取成功！',
                    'data' => $packageIds  // 直接返回ID数组，供 getPackageDetails 使用
                ]);

            } catch (\Exception $e) {
                trace("获取用户权限异常：{$e->getMessage()}\n" . $e->getTraceAsString());
                return json(['code' => 0, 'info' => '系统异常，请稍后重试！']);
            }
        }
    }

    /**
     * 批量授权
     * @auth true
     */
    public function batchAuth()
    {
        if ($this->request->isPost()) {
            try {
                $data = $this->_vali([
                    'user_ids.require' => '请选择管理员！',
                    'package_ids.require' => '请选择包名！'
                ]);

                // 验证所选用户是否都有包名管理权限
                foreach ($data['user_ids'] as $userId) {
                    if (!AdminService::instance()->check('package/index', $userId)) {
                        return json(['code' => 0, 'info' => '选中的用户中有人没有包名管理权限！']);
                    }
                }

                // 开启事务
                $this->app->db->startTrans();
                try {
                    foreach ($data['user_ids'] as $userId) {
                        // 删除原有权限
                        $this->app->db->name($this->table)
                            ->where('user_id', $userId)
                            ->delete();

                        // 添加新权限
                        $insertData = [];
                        foreach ($data['package_ids'] as $packageId) {
                            $insertData[] = [
                                'user_id' => $userId,
                                'package_id' => $packageId,
                                'create_at' => date('Y-m-d H:i:s')
                            ];
                        }

                        if (!empty($insertData)) {
                            $this->app->db->name($this->table)->insertAll($insertData);
                        }
                    }

                    $this->app->db->commit();
                    sysoplog('积分墙权限', '批量授权成功');

                    return json(['code' => 1, 'info' => '批量授权成功！']);
                } catch (\Exception $e) {
                    $this->app->db->rollback();
                    throw $e;
                }
            } catch (\Exception $e) {
                trace("批量授权异常：" . $e->getMessage());
                return json(['code' => 0, 'info' => '系统异常，请稍后重���！']);
            }
        }
    }

    /**
     * 清空
     * @auth true
     */
    public function clearAuth()
    {
        if ($this->request->isPost()) {
            try {
                $post = $this->request->post();

                // 验证用户ID
                if (empty($post['user_ids']) || !is_array($post['user_ids'])) {
                    return json(['code' => 0, 'info' => '选择管理员！']);
                }

                // 开启事务
                $this->app->db->startTrans();
                try {
                    foreach ($post['user_ids'] as $userId) {
                        // 删除用户的所有权限
                        $this->app->db->name($this->table)
                            ->where('user_id', $userId)
                            ->delete();
                    }

                    $this->app->db->commit();
                    sysoplog('积分墙权限', '权限清空成功');

                    return json(['code' => 1, 'info' => '权限清空成功！']);
                } catch (\Exception $e) {
                    $this->app->db->rollback();
                    trace('清空权限事务异常：' . $e->getMessage());
                    throw $e;
                }
            } catch (\Exception $e) {
                trace("清空权限异常：" . $e->getMessage());
                return json(['code' => 0, 'info' => '系统异常，请稍后重试！']);
            }
        }
    }

    /**
     * 获取包名详情
     */
    public function getPackageDetails()
    {
        if ($this->request->isPost()) {
            try {
                $packageIds = $this->request->post('package_ids/a', []);

                // 记录请求参数
                trace("getPackageDetails 请求参数：" . json_encode([
                    'package_ids' => $packageIds
                ], JSON_UNESCAPED_UNICODE));

                // 如果没有包名ID，返回空数组
                if (empty($packageIds)) {
                    trace("getPackageDetails：包名ID为空");
                    return json([
                        'code' => 1,
                        'info' => '获取成功！',
                        'data' => []
                    ]);
                }

                // 获取包名详情
                $packages = $this->app->db->name('offer_package')
                    ->whereIn('id', $packageIds)
                    ->field('id,package_name,name,status')
                    ->select()
                    ->toArray();

                return json([
                    'code' => 1,
                    'info' => '获取成功！',
                    'data' => $packages
                ]);

            } catch (\Exception $e) {
                trace("getPackageDetails 异常：" . $e->getMessage());
                trace("getPackageDetails 异常堆栈：" . $e->getTraceAsString());
                return json(['code' => 0, 'info' => '系统异常，请稍后重试！#3']);
            }
        }
    }

    /**
     * 获取未授权的包名列表
     * @auth true
     */
    public function getUnauthorizedPackages()
    {
        // 同时支持 GET 和 POST 请求
        $userId = $this->request->param('user_id/d', 0);
        $keyword = $this->request->param('keyword/s', '');
        $page = $this->request->param('page/d', 1);
        $limit = $this->request->param('limit/d', 10);

        try {
            if (empty($userId)) {
                return json(['code' => 0, 'info' => '参数错误！']);
            }

            // 获取已授权的包名ID
            $authorizedIds = $this->app->db->name($this->table)
                ->where('user_id', $userId)
                ->column('package_id');

            // 构建查询条件
            $where = [];
            // 排除已授权的包名
            if (!empty($authorizedIds)) {
                $where[] = ['id', 'not in', $authorizedIds];
            }
            // 搜索条件
            if ($keyword !== '') {
                $where[] = ['package_name|name', 'like', "%{$keyword}%"];
            }
            // 只显示启用的包名
            $where[] = ['status', '=', 1];

            // 查询数据
            $query = $this->app->db->name('offer_package');

            // 获取总数
            $total = $query->where($where)->count();

            // 获取列表
            $list = $query->where($where)
                ->field('id,package_name,name,status')
                ->order('status desc,id desc')
                ->limit(($page - 1) * $limit, $limit)
                ->select()
                ->toArray();

            // 记录调试信息
            trace('未授权包名查询：' . json_encode([
                    'user_id' => $userId,
                    'keyword' => $keyword,
                    'where' => $where,
                    'sql' => $query->getLastSql(),
                    'total' => $total,
                    'list_count' => count($list)
                ], JSON_UNESCAPED_UNICODE));

            return json([
                'code' => 0,  // layui table 要求成功码为 0
                'msg' => '',  // layui table 使用 msg 而不是 info
                'count' => $total,
                'data' => $list
            ]);
        } catch (\Exception $e) {
            trace("获取未授权包名异常：" . $e->getMessage() . "\n" . $e->getTraceAsString());
            return json(['code' => 1, 'msg' => '系统异常，请稍后重试！']);  // layui table 要求失败码为非 0
        }
    }

    /**
     * 批量添加授权
     * @auth true
     */
    public function addAuth()
    {
        if ($this->request->isPost()) {
            try {
                $userId = $this->request->post('user_id/d', 0);
                $packageIds = $this->request->post('package_ids/a');
                $isAll = $this->request->post('is_all/d', 0);  // 是否全部授权

                if (empty($userId)) {
                    return json(['code' => 0, 'info' => '参数错误！']);
                }

                // 开启事务
                $this->app->db->startTrans();
                try {
                    if ($isAll) {
                        // 优化: 使用INSERT INTO SELECT语法直接插入
                        $sql = "INSERT INTO {$this->table} (user_id, package_id, create_at)
                               SELECT :user_id, id, :create_at 
                               FROM offer_package 
                               WHERE status = 1 
                               AND id NOT IN (
                                   SELECT package_id 
                                   FROM {$this->table} 
                                   WHERE user_id = :user_id2
                               )";
                        
                        $this->app->db->execute($sql, [
                            'user_id' => $userId,
                            'user_id2' => $userId,
                            'create_at' => date('Y-m-d H:i:s')
                        ]);
                    } else {
                        if (empty($packageIds)) {
                            return json(['code' => 0, 'info' => '请选择要授权的包名！']);
                        }
                        
                        // 过滤掉已授权的包名
                        $existIds = $this->app->db->name($this->table)
                            ->where('user_id', $userId)
                            ->whereIn('package_id', $packageIds)
                            ->column('package_id');
                        
                        $newPackageIds = array_diff($packageIds, $existIds);
                        
                        if (!empty($newPackageIds)) {
                            $insertData = array_map(function($packageId) use ($userId) {
                                return [
                                    'user_id' => $userId,
                                    'package_id' => $packageId,
                                    'create_at' => date('Y-m-d H:i:s')
                                ];
                            }, $newPackageIds);
                            
                            $this->app->db->name($this->table)->insertAll($insertData);
                        }
                    }

                    $this->app->db->commit();
                    sysoplog('积分墙权限', '授权添加成功！');

                    return json(['code' => 1, 'info' => '授权添加成功！']);
                } catch (\Exception $e) {
                    $this->app->db->rollback();
                    throw $e;
                }
            } catch (\Exception $e) {
                trace("添加授权异常：" . $e->getMessage());
                return json(['code' => 0, 'info' => '系统异常，请稍后重试！']);
            }
        }
    }

    /**
     * 移除单个包名权限
     * @auth true
     */
    public function removeAuth()
    {
        if ($this->request->isPost()) {
            try {
                $userId = $this->request->post('user_id/d', 0);
                $packageId = $this->request->post('package_id/d', 0);

                if (empty($userId) || empty($packageId)) {
                    return json(['code' => 0, 'info' => '参数错误！']);
                }

                $result = $this->app->db->name($this->table)
                    ->where([
                        'user_id' => $userId,
                        'package_id' => $packageId
                    ])
                    ->delete();

                if ($result !== false) {
                    sysoplog('积分墙权限', '权限移除成功！');

                    return json(['code' => 1, 'info' => '权限移除成功！']);
                } else {
                    return json(['code' => 0, 'info' => '权限移除失败！']);
                }
            } catch (\Exception $e) {
                trace("移除权限异常：" . $e->getMessage());
                return json(['code' => 0, 'info' => '系统异常，请稍后重试！']);
            }
        }
    }

    /**
     * 首页批量授权保存
     * @auth true
     */
    public function batchSaveAuth()
    {
        if ($this->request->isPost()) {
            try {
                $data = $this->_vali([
                    'user_ids.require' => '请选择管理员！',
                    'package_ids.require' => '请选择包名！'
                ]);

                // 开启事务
                $this->app->db->startTrans();
                try {
                    foreach ($data['user_ids'] as $userId) {
                        // 删除原有权限
                        $this->app->db->name($this->table)
                            ->where('user_id', $userId)
                            ->delete();

                        // 添加新权限
                        $insertData = [];
                        foreach ($data['package_ids'] as $packageId) {
                            $insertData[] = [
                                'user_id' => $userId,
                                'package_id' => $packageId,
                                'create_at' => date('Y-m-d H:i:s')
                            ];
                        }

                        if (!empty($insertData)) {
                            $this->app->db->name($this->table)->insertAll($insertData);
                        }
                    }

                    $this->app->db->commit();
                    sysoplog('积分墙权限', '批量授权成功！');

                    return json(['code' => 1, 'info' => '批量授权成功！']);
                } catch (\Exception $e) {
                    $this->app->db->rollback();
                    throw $e;
                }
            } catch (\Exception $e) {
                trace("首页批量授权异常：" . $e->getMessage());
                return json(['code' => 0, 'info' => '系统异常，请稍后重试！']);
            }
        }
    }

    /**
     * 批量移除包名权限
     * @auth true
     */
    public function batchRemoveAuth()
    {
        if ($this->request->isPost()) {
            try {
                $userId = $this->request->post('user_id/d', 0);
                $packageIds = $this->request->post('package_ids/a');

                if (empty($userId) || empty($packageIds)) {
                    return json(['code' => 0, 'info' => '参数错误！']);
                }

                // 开启事务
                $this->app->db->startTrans();
                try {
                    // 批量删除权限
                    $result = $this->app->db->name($this->table)
                        ->where('user_id', $userId)
                        ->whereIn('package_id', $packageIds)
                        ->delete();

                    if ($result !== false) {
                        $this->app->db->commit();
                        sysoplog('积分墙权限', '批量移除成功！');

                        return json(['code' => 1, 'info' => '批量移除成功！']);
                    } else {
                        $this->app->db->rollback();
                        return json(['code' => 0, 'info' => '批量移除失败！']);
                    }
                } catch (\Exception $e) {
                    $this->app->db->rollback();
                    throw $e;
                }
            } catch (\Exception $e) {
                trace("批移除权限异：" . $e->getMessage());
                return json(['code' => 0, 'info' => '系统异常，请稍后重试！']);
            }
        }
    }

    /**
     * 显示权限详情页面
     * @auth true
     */
    public function authDetail()
    {
        try {
            $userId = input('user_id/d');
            if (!$userId) {
                $this->error('参数错误');
            }

            // 获取用户基本信息
            $user = $this->app->db->name('system_user')
                ->where('id', $userId)
                ->field('id,username,status,create_at')
                ->find();

            if (!$user) {
                $this->error('用户不存在');
            }

            // 获取用户权限统计
            $stats = [
                'total' => $this->app->db->name($this->table)
                    ->where('user_id', $userId)
                    ->count(),
                'active' => $this->app->db->name('offer_package')
                    ->alias('p')
                    ->join("{$this->table} a", 'p.id = a.package_id')
                    ->where([
                        'a.user_id' => $userId,
                        'p.status' => 1
                    ])
                    ->count()
            ];

            $this->assign([
                'user' => $user,
                'stats' => $stats,
                'title' => '授权包名管理'
            ]);
            
            return $this->fetch();
        } catch (\Exception $e) {
            $this->app->log->error("显示权限详情页面异常：{$e->getMessage()}");
            $this->error('系统异常，请稍后重试！');
        }
    }

    /**
     * 获取权限详情数据
     * @auth true
     * @api true
     */
    public function getAuthDetailData()
    {
        try {
            $get = $this->_vali([
                'user_id.require' => '用户ID不能为空',
                'type.require' => '类型不能为空',
                'page.default' => 1,
                'limit.default' => 20,
                'keyword.default' => '',
                'sort.default' => 'id',
                'order.default' => 'desc'
            ]);

            // 确保分页参数为整数
            $page = intval($get['page']);
            $limit = intval($get['limit']);

            // 构建基础查询
            $query = $this->app->db->name('offer_package')
                ->alias('p');

            if ($get['type'] === 'authorized') {
                // 已授权包名查询
                $query->join("{$this->table} a", 'p.id = a.package_id')
                    ->where('a.user_id', $get['user_id']);
            } else {
                // 未授权包名查询
                $query->whereNotExists(function($query) use ($get) {
                    $query->table($this->table)
                        ->where('package_id=p.id')
                        ->where('user_id', $get['user_id']);
                })
                ->where('p.status', 1);
            }

            // 关键词搜索
            if ($get['keyword'] !== '') {
                $query->whereLike('p.package_name|p.name', "%{$get['keyword']}%");
            }

            // 获取总数
            $total = $query->count();

            // 获取列表数据
            $list = $query->field([
                    'p.id',
                    'p.package_name',
                    'p.name',
                    'p.status',
                    $get['type'] === 'authorized' ? 'a.create_at' : 'p.add_time as create_at'
                ])
                ->order("{$get['sort']} {$get['order']}")
                ->page($page, $limit)  // 使用转换后的整数值
                ->select()
                ->toArray();

            // 格式化时间
            foreach ($list as &$item) {
                $item['create_at'] = format_datetime($item['create_at']);
                $item['status_text'] = $item['status'] ? '启用' : '停用';
            }

            return json([
                'code' => 0,
                'msg' => '',
                'count' => $total,
                'data' => $list
            ]);

        } catch (\Exception $e) {
            trace("获取权限详情数据异常：" . $e->getMessage() . "\n" . $e->getTraceAsString());
            return json(['code' => 1, 'msg' => '系统异常，请稍后重试！']);
        }
    }

    /**
     * 获取已授权的包名列表
     * @auth true
     */
    public function getAuthorizedPackages()
    {
        try {
            $userId = $this->request->param('user_id/d', 0);
            $keyword = $this->request->param('keyword/s', '');
            $page = $this->request->param('page/d', 1);
            $limit = $this->request->param('limit/d', 10);

            if (empty($userId)) {
                return json(['code' => 1, 'msg' => '参数错误']);
            }

            // 优化1: 使用子查询优化 JOIN
            $query = $this->app->db->name('offer_package')
                ->whereExists(function($query) use ($userId) {
                    $query->table($this->table)
                        ->where('package_id=offer_package.id')
                        ->where('user_id', $userId);
                })
                ->where('status', 1);

            // 优化2: 添加索引字段的索条件
            if ($keyword !== '') {
                $query->where(function($query) use ($keyword) {
                    $query->whereOr([
                        ['package_name', 'like', "%{$keyword}%"],
                        ['name', 'like', "%{$keyword}%"]
                    ]);
                });
            }

            // 优化3: 使用子查询获取总数,避免重复JOIN
            $total = $query->count();

            // 优化4: 只查询需要的字段
            $list = $query->field([
                    'id',
                    'package_name',
                    'name', 
                    'status',
                    "(SELECT create_at FROM {$this->table} WHERE package_id=offer_package.id AND user_id={$userId} LIMIT 1) as create_at"
                ])
                ->order('id desc')
                ->page($page, $limit)
                ->select()
                ->toArray();

            // 优化5: 添加缓存
            $cacheKey = "auth_packages_{$userId}_{$page}_{$limit}_" . md5($keyword);
            cache($cacheKey, $list, 300); // 缓存5分钟

            return json([
                'code' => 0,
                'msg' => '',
                'count' => $total,
                'data' => $list
            ]);
        } catch (\Exception $e) {
            trace("获取已授权包名列表异常：" . $e->getMessage() . "\n" . $e->getTraceAsString());
            return json(['code' => 1, 'msg' => '系统异常，请稍后重试！']);
        }
    }

    /**
     * 获取授权包名列表（分页）
     * @auth true
     * @api true
     */
    public function getAuthPackageList()
    {
        try {
            $get = $this->_vali([
                'user_id.require' => '用户ID不能为空',
                'page.default' => 1,
                'limit.default' => 10,
                'keyword.default' => '',
                'status.default' => 1,
                'sort.default' => 'id',
                'order.default' => 'desc'
            ]);

            // 构建基础查询
            $query = $this->app->db->name('offer_package')
                ->alias('p')
                ->join("{$this->table} a", 'p.id = a.package_id')
                ->where([
                    'a.user_id' => $get['user_id'],
                    'p.status' => $get['status']
                ]);

            // 关键词搜索
            if ($get['keyword'] !== '') {
                $query->whereLike('p.package_name|p.name', "%{$get['keyword']}%");
            }

            // 获取总数
            $total = $query->count();

            // 获取分页数据
            $list = $query->field([
                    'p.id',
                    'p.package_name',
                    'p.name',
                    'p.status',
                    'a.create_at',
                    'p.update_time'
                ])
                ->order("{$get['sort']} {$get['order']}")
                ->limit(($get['page'] - 1) * $get['limit'], $get['limit'])
                ->select()
                ->toArray();

            // 格式化时间
            foreach ($list as &$item) {
                $item['create_at'] = format_datetime($item['create_at']);
                $item['update_time'] = format_datetime($item['update_time']);
            }

            // 使用缓存
            $cacheKey = "auth_package_list_{$get['user_id']}_{$get['page']}_{$get['limit']}_" . md5($get['keyword']);
            cache($cacheKey, [
                'total' => $total,
                'list' => $list
            ], 300); // 缓存5分钟

            return json([
                'code' => 0,
                'msg' => 'success',
                'total' => $total,
                'list' => $list,
                'page' => $get['page'],
                'limit' => $get['limit']
            ]);
        } catch (\Exception $e) {
            $this->app->log->error("获取授权包名列表异常：{$e->getMessage()}");
            return json([
                'code' => 1,
                'msg' => '获取数据失败：' . $e->getMessage()
            ]);
        }
    }

    /**
     * 获取授权包名统计
     * @auth true
     * @api true
     */
    public function getAuthPackageStats()
    {
        try {
            $userId = input('user_id/d', 0);
            if (empty($userId)) {
                return json(['code' => 1, 'msg' => '用户ID不能为空']);
            }

            // 获取统计数据
            $stats = [
                'total' => $this->app->db->name($this->table)
                    ->where('user_id', $userId)
                    ->count(),
                'active' => $this->app->db->name('offer_package')
                    ->alias('p')
                    ->join("{$this->table} a", 'p.id = a.package_id')
                    ->where([
                        'a.user_id' => $userId,
                        'p.status' => 1
                    ])
                    ->count(),
                'latest' => $this->app->db->name($this->table)
                    ->where('user_id', $userId)
                    ->order('create_at desc')
                    ->value('create_at')
            ];

            $stats['latest'] = $stats['latest'] ? format_datetime($stats['latest']) : '';

            return json([
                'code' => 0,
                'msg' => 'success',
                'data' => $stats
            ]);
        } catch (\Exception $e) {
            $this->app->log->error("获取授权包名统计异常：{$e->getMessage()}");
            return json([
                'code' => 1,
                'msg' => '获取统计失败：' . $e->getMessage()
            ]);
        }
    }

}