<?php
/**
 * HuSNS - 一款免费开源的社交平台
 * 
 * @author  HYR
 * @QQ      281900864
 * @website https://huyourui.com
 * @license MIT
 * @声明    严禁用于违法违规用途
 */
class PointModel extends Model
{
    protected $table = 'point_rules';

    public function getActiveRules()
    {
        return $this->db->fetchAll(
            "SELECT * FROM __PREFIX__point_rules WHERE status = 1 ORDER BY id ASC"
        );
    }

    public function getAllRules()
    {
        return $this->db->fetchAll(
            "SELECT * FROM __PREFIX__point_rules ORDER BY id ASC"
        );
    }

    public function getRuleByAction($action)
    {
        return $this->db->fetch(
            "SELECT * FROM __PREFIX__point_rules WHERE action = ?",
            [$action]
        );
    }

    public function createRule($data)
    {
        $data['created_at'] = time();
        $data['updated_at'] = time();
        return $this->insert($data);
    }

    public function updateRule($id, $data)
    {
        $data['updated_at'] = time();
        return $this->update($id, $data);
    }

    public function deleteRule($id)
    {
        return $this->delete($id);
    }

    public function toggleStatus($id)
    {
        $rule = $this->find($id);
        if (!$rule) {
            return false;
        }
        
        $newStatus = $rule['status'] ? 0 : 1;
        return $this->update($id, ['status' => $newStatus, 'updated_at' => time()]);
    }

    public function getTodayCount($userId, $action)
    {
        $todayStart = strtotime(date('Y-m-d 00:00:00'));
        $todayEnd = strtotime(date('Y-m-d 23:59:59'));
        
        return (int)$this->db->fetch(
            "SELECT COUNT(*) as count FROM __PREFIX__point_logs WHERE user_id = ? AND action = ? AND created_at BETWEEN ? AND ?",
            [$userId, $action, $todayStart, $todayEnd]
        )['count'];
    }

    public function addLog($userId, $action, $points, $balance, $relatedType = null, $relatedId = null, $remark = '')
    {
        return $this->db->insert('point_logs', [
            'user_id' => $userId,
            'action' => $action,
            'points' => $points,
            'balance' => $balance,
            'related_type' => $relatedType,
            'related_id' => $relatedId,
            'remark' => $remark,
            'created_at' => time()
        ]);
    }

    public function getUserLogs($userId, $page = 1, $pageSize = 20)
    {
        $offset = ($page - 1) * $pageSize;
        
        $logs = $this->db->fetchAll(
            "SELECT * FROM __PREFIX__point_logs WHERE user_id = ? ORDER BY created_at DESC LIMIT ?, ?",
            [$userId, $offset, $pageSize]
        );
        
        $total = $this->db->count('point_logs', 'user_id = ?', [$userId]);
        
        return [
            'items' => $logs,
            'total' => $total,
            'page' => $page,
            'pageSize' => $pageSize,
            'totalPages' => ceil($total / $pageSize)
        ];
    }
    
    /**
     * 检查今日是否已签到
     * @param int $userId 用户ID
     * @return bool
     */
    public function hasSignedInToday($userId)
    {
        $todayStart = strtotime(date('Y-m-d 00:00:00'));
        $todayEnd = strtotime(date('Y-m-d 23:59:59'));
        
        $count = $this->db->fetch(
            "SELECT COUNT(*) as count FROM __PREFIX__point_logs WHERE user_id = ? AND action = 'signin' AND created_at BETWEEN ? AND ?",
            [$userId, $todayStart, $todayEnd]
        )['count'];
        
        return $count > 0;
    }
    
    /**
     * 获取连续签到天数
     * @param int $userId 用户ID
     * @return int
     */
    public function getSignInDays($userId)
    {
        $today = date('Y-m-d');
        $days = 0;
        
        // 从今天开始往前遍历
        for ($i = 0; $i < 365; $i++) {
            $checkDate = date('Y-m-d', strtotime("-$i day"));
            $startTime = strtotime($checkDate . ' 00:00:00');
            $endTime = strtotime($checkDate . ' 23:59:59');
            
            $count = $this->db->fetch(
                "SELECT COUNT(*) as count FROM __PREFIX__point_logs WHERE user_id = ? AND action = 'signin' AND created_at BETWEEN ? AND ?",
                [$userId, $startTime, $endTime]
            )['count'];
            
            if ($count > 0) {
                $days++;
            } else if ($i > 0) {
                // 如果不是第一天就断签了，停止计数
                break;
            }
        }
        
        return $days;
    }
    
    /**
     * 签到
     * @param int $userId 用户ID
     * @return bool
     */
    public function signIn($userId)
    {
        if ($this->hasSignedInToday($userId)) {
            return false;
        }
        
        // 获取签到积分规则
        $rule = $this->getRuleByAction('signin');
        $points = $rule ? $rule['points'] : 10;
        
        // 获取当前积分
        $userModel = new UserModel();
        $user = $userModel->find($userId);
        $currentPoints = (int)($user['points'] ?? 0);
        
        // 更新用户积分
        $newPoints = $currentPoints + $points;
        $userModel->update($userId, ['points' => $newPoints]);
        
        // 添加积分日志
        $this->addLog($userId, 'signin', $points, $newPoints);
        
        return true;
    }

    /**
     * 获取等级配置列表
     */
    public function getLevelConfig()
    {
        return [
            ['level' => 1, 'name' => '新手', 'min_points' => 0, 'max_points' => 100, 'icon' => '🌱'],
            ['level' => 2, 'name' => '初级会员', 'min_points' => 101, 'max_points' => 500, 'icon' => '🌿'],
            ['level' => 3, 'name' => '中级会员', 'min_points' => 501, 'max_points' => 1000, 'icon' => '🌳'],
            ['level' => 4, 'name' => '高级会员', 'min_points' => 1001, 'max_points' => 3000, 'icon' => '🌟'],
            ['level' => 5, 'name' => '黄金会员', 'min_points' => 3001, 'max_points' => 5000, 'icon' => '⭐'],
            ['level' => 6, 'name' => '铂金会员', 'min_points' => 5001, 'max_points' => 10000, 'icon' => '💎'],
            ['level' => 7, 'name' => '钻石会员', 'min_points' => 10001, 'max_points' => 20000, 'icon' => '💠'],
            ['level' => 8, 'name' => '至尊会员', 'min_points' => 20001, 'max_points' => 50000, 'icon' => '👑'],
            ['level' => 9, 'name' => '传奇会员', 'min_points' => 50001, 'max_points' => 100000, 'icon' => '🏆'],
            ['level' => 10, 'name' => '神话会员', 'min_points' => 100001, 'max_points' => 9999999, 'icon' => '👑'],
        ];
    }

    /**
     * 根据积分获取等级信息
     * @param int $points 积分数量
     * @return array 等级信息
     */
    public function getLevelByPoints($points)
    {
        $levels = $this->getLevelConfig();
        
        foreach ($levels as $level) {
            if ($points >= $level['min_points'] && $points <= $level['max_points']) {
                return $level;
            }
        }
        
        return $levels[count($levels) - 1];
    }

    /**
     * 获取用户等级进度
     * @param int $points 当前积分
     * @return array 进度信息
     */
    public function getLevelProgress($points)
    {
        $level = $this->getLevelByPoints($points);
        $nextLevel = null;

        $levels = $this->getLevelConfig();
        foreach ($levels as $idx => $l) {
            if ($l['level'] == $level['level'] && isset($levels[$idx + 1])) {
                $nextLevel = $levels[$idx + 1];
                break;
            }
        }

        $currentMin = $level['min_points'];
        $currentMax = $level['max_points'];
        $progress = 0;

        if ($currentMax > $currentMin) {
            $progress = ((($points - $currentMin) / ($currentMax - $currentMin)) * 100);
        }

        return [
            'current_level' => $level,
            'next_level' => $nextLevel,
            'current_points' => $points,
            'progress' => round($progress, 1),
            'points_to_next' => $nextLevel ? ($nextLevel['min_points'] - $points) : 0
        ];
    }

    // ==================== 签到相关方法 ====================

    /**
     * 获取签到配置
     */
    public function getSigninConfig()
    {
        try {
            $table = $this->db->table('config');
            $config = $this->db->fetch("SELECT * FROM `{$table}` WHERE `name` = 'signin_config'");
            if ($config && !empty($config['value'])) {
                $decoded = json_decode($config['value'], true);
                if (is_array($decoded)) {
                    return array_merge([
                        'enabled' => 1,
                        'base_points' => 10,
                        'continuous_bonus' => []
                    ], $decoded);
                }
            }
        } catch (Exception $e) {
            // 表可能不存在，返回默认值
        }
        return [
            'enabled' => 1,
            'base_points' => 10,
            'continuous_bonus' => []
        ];
    }

    /**
     * 保存签到配置
     */
    public function saveSigninConfig($data)
    {
        $json = json_encode($data, JSON_UNESCAPED_UNICODE);
        $table = $this->db->table('config');

        try {
            $existing = $this->db->fetch("SELECT id FROM `{$table}` WHERE `name` = 'signin_config'");

            if ($existing) {
                $this->db->update('config', [
                    'value' => $json
                ], "`name` = 'signin_config'");
            } else {
                $this->db->insert('config', [
                    'name' => 'signin_config',
                    'value' => $json,
                    'group' => 'point',
                    'description' => '签到配置'
                ]);
            }
        } catch (Exception $e) {
            // 如果表不存在，使用缓存存储
            Cache::set('signin_config', $data, 86400 * 365);
        }
    }

    /**
     * 获取签到统计数据
     */
    public function getSigninStats()
    {
        try {
            $table = $this->db->table('point_logs');

            $todayStart = strtotime(date('Y-m-d 00:00:00'));
            $todayEnd = strtotime(date('Y-m-d 23:59:59'));
            $yesterdayStart = strtotime(date('Y-m-d 00:00:00', strtotime('-1 day')));
            $yesterdayEnd = strtotime(date('Y-m-d 23:59:59', strtotime('-1 day')));
            $monthStart = strtotime(date('Y-m-01 00:00:00'));

            $todayCount = (int)$this->db->fetch(
                "SELECT COUNT(*) as count FROM `{$table}` WHERE action = 'signin' AND created_at BETWEEN ? AND ?",
                [$todayStart, $todayEnd]
            )['count'];

            $yesterdayCount = (int)$this->db->fetch(
                "SELECT COUNT(*) as count FROM `{$table}` WHERE action = 'signin' AND created_at BETWEEN ? AND ?",
                [$yesterdayStart, $yesterdayEnd]
            )['count'];

            $monthCount = (int)$this->db->fetch(
                "SELECT COUNT(*) as count FROM `{$table}` WHERE action = 'signin' AND created_at >= ?",
                [$monthStart]
            )['count'];

            $totalCount = (int)$this->db->fetch(
                "SELECT COUNT(*) as count FROM `{$table}` WHERE action = 'signin'"
            )['count'];

            $totalUsers = (int)$this->db->fetch(
                "SELECT COUNT(DISTINCT user_id) as count FROM `{$table}` WHERE action = 'signin'"
            )['count'];

            return [
                'today_count' => $todayCount,
                'yesterday_count' => $yesterdayCount,
                'month_count' => $monthCount,
                'total_count' => $totalCount,
                'total_users' => $totalUsers
            ];
        } catch (Exception $e) {
            return [
                'today_count' => 0,
                'yesterday_count' => 0,
                'month_count' => 0,
                'total_count' => 0,
                'total_users' => 0
            ];
        }
    }

    /**
     * 获取每日签到数据
     */
    public function getSigninDaily($days = 30)
    {
        try {
            $table = $this->db->table('point_logs');
            $result = [];

            for ($i = $days - 1; $i >= 0; $i--) {
                $date = date('Y-m-d', strtotime("-$i day"));
                $start = strtotime($date . ' 00:00:00');
                $end = strtotime($date . ' 23:59:59');

                $count = (int)$this->db->fetch(
                    "SELECT COUNT(*) as count FROM `{$table}` WHERE action = 'signin' AND created_at BETWEEN ? AND ?",
                    [$start, $end]
                )['count'];

                $result[] = [
                    'date' => $date,
                    'count' => $count
                ];
            }
            return $result;
        } catch (Exception $e) {
            return [];
        }
    }

    /**
     * 获取签到记录
     */
    public function getSigninLogs($page = 1, $limit = 20, $keyword = '')
    {
        try {
            $table = $this->db->table('point_logs');
            $offset = ($page - 1) * $limit;
            $where = "WHERE pl.action = 'signin'";
            $params = [];

            if ($keyword) {
                $where .= " AND (u.name LIKE ? OR u.username LIKE ?)";
                $params[] = "%{$keyword}%";
                $params[] = "%{$keyword}%";
            }

            $total = (int)$this->db->fetch(
                "SELECT COUNT(*) as count FROM `{$table}` pl
                 LEFT JOIN `{$this->db->table('users')}` u ON pl.user_id = u.id
                 {$where}",
                $params
            )['count'];

            $logs = $this->db->fetchAll(
                "SELECT pl.*, u.name as user_name, u.username, u.avatar as user_avatar
                 FROM `{$table}` pl
                 LEFT JOIN `{$this->db->table('users')}` u ON pl.user_id = u.id
                 {$where}
                 ORDER BY pl.created_at DESC
                 LIMIT {$offset}, {$limit}",
                $params
            );

            return [
                'logs' => $logs,
                'total' => $total,
                'page' => $page,
                'pages' => $total > 0 ? ceil($total / $limit) : 0
            ];
        } catch (Exception $e) {
            return [
                'logs' => [],
                'total' => 0,
                'page' => $page,
                'pages' => 0
            ];
        }
    }

    /**
     * 获取签到排行榜
     */
    public function getSigninLeaderboard($page = 1, $limit = 50)
    {
        try {
            $table = $this->db->table('point_logs');
            $usersTable = $this->db->table('users');
            $offset = ($page - 1) * $limit;

            $total = (int)$this->db->fetch(
                "SELECT COUNT(DISTINCT user_id) as count FROM `{$table}` WHERE action = 'signin'"
            )['count'];

            $users = $this->db->fetchAll(
                "SELECT u.id, u.name, u.username, u.avatar,
                        COUNT(*) as signin_count,
                        MAX(pl.created_at) as last_signin,
                        SUM(pl.points) as total_points
                 FROM `{$table}` pl
                 LEFT JOIN `{$usersTable}` u ON pl.user_id = u.id
                 WHERE pl.action = 'signin'
                 GROUP BY u.id, u.name, u.username, u.avatar
                 ORDER BY signin_count DESC, last_signin DESC
                 LIMIT {$offset}, {$limit}"
            );

            return [
                'users' => $users,
                'total' => $total,
                'page' => $page,
                'pages' => $total > 0 ? ceil($total / $limit) : 0
            ];
        } catch (Exception $e) {
            return [
                'users' => [],
                'total' => 0,
                'page' => $page,
                'pages' => 0
            ];
        }
    }
}
