package com.dora.service.impl;

import com.dora.dto.AdminAuthDto;
import com.dora.dto.ApiResponse;
import com.dora.entity.AdminUser;
import com.dora.mapper.AdminUserMapper;
import com.dora.mapper.WithdrawRequestMapper;
import com.dora.mapper.UserBalanceMapper;
import com.dora.mapper.WorkflowCopyStatMapper;
import com.dora.mapper.VideoViewStatMapper;
import com.dora.service.AdminAuthService;
import com.dora.service.JwtTokenManager;
import com.dora.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;

/**
 * 管理员认证服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AdminAuthServiceImpl implements AdminAuthService {

    private final AdminUserMapper adminUserMapper;
    private final WithdrawRequestMapper withdrawRequestMapper;
    private final UserBalanceMapper userBalanceMapper;
    private final WorkflowCopyStatMapper workflowCopyStatMapper;
    private final VideoViewStatMapper videoViewStatMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;
    private final JwtTokenManager jwtTokenManager;

    @Override
    @Transactional
    public ApiResponse<String> firstTimeRegister(AdminAuthDto.AdminRegisterRequest request) {
        try {
            // 1. 检查系统是否已有管理员账号
            if (adminUserMapper.hasAnyAdmin()) {
                return ApiResponse.error(403, "系统已存在管理员账号，无法进行首次注册");
            }

            // 2. 强制设置为管理员角色（首次注册必须是管理员）
            request.setRole(1);

            // 3. 调用普通注册方法
            ApiResponse<String> result = register(request);
            
            if (result.getCode() == 200) {
                log.info("系统首次管理员注册成功：username={}", request.getUsername());
                return ApiResponse.success("系统首次管理员注册成功，您现在可以使用管理员权限");
            }
            
            return result;

        } catch (Exception e) {
            log.error("首次管理员注册失败", e);
            return ApiResponse.error("首次管理员注册失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> register(AdminAuthDto.AdminRegisterRequest request) {
        try {
            // 1. 参数验证
            if (!request.getPassword().equals(request.getConfirmPassword())) {
                return ApiResponse.error(400, "两次输入的密码不一致");
            }

            // 2. 检查用户名是否已存在
            if (adminUserMapper.existsByUsername(request.getUsername())) {
                return ApiResponse.error(400, "用户名已存在");
            }

            // 3. 创建管理员用户
            AdminUser adminUser = new AdminUser();
            adminUser.setUsername(request.getUsername());
            adminUser.setPasswordHash(passwordEncoder.encode(request.getPassword()));
            adminUser.setRole(request.getRole());
            adminUser.setCreateTime(LocalDateTime.now());
            adminUser.setUpdateTime(LocalDateTime.now());
            adminUser.setIsDeleted(0);

            // 4. 保存到数据库
            int result = adminUserMapper.insert(adminUser);
            if (result > 0) {
                log.info("管理员用户注册成功：username={}, role={}", request.getUsername(), request.getRole());
                return ApiResponse.success("管理员注册成功");
            } else {
                return ApiResponse.error("管理员注册失败");
            }

        } catch (Exception e) {
            log.error("管理员注册失败", e);
            return ApiResponse.error("管理员注册失败：" + e.getMessage());
        }
    }

    @Override
    public ApiResponse<AdminAuthDto.AdminLoginResponse> login(AdminAuthDto.AdminLoginRequest request) {
        try {
            // 1. 查询管理员用户
            AdminUser adminUser = adminUserMapper.selectByUsername(request.getUsername());
            if (adminUser == null) {
                return ApiResponse.error(401, "用户名或密码错误");
            }

            // 2. 验证密码
            if (!passwordEncoder.matches(request.getPassword(), adminUser.getPasswordHash())) {
                return ApiResponse.error(401, "用户名或密码错误");
            }

            // 3. 生成JWT token
            String token = jwtUtil.generateAdminToken(
                adminUser.getId(), 
                adminUser.getUsername(), 
                adminUser.getRole()
            );

            // 4. 将token添加到管理器中（管理员暂不限制设备数）
            String jwtId = jwtUtil.getJwtIdFromToken(token);
            jwtTokenManager.addAdminToken(adminUser.getId(), jwtId, System.currentTimeMillis());

            // 5. 计算过期时间
            Date expirationDate = jwtUtil.getExpirationDateFromToken(token);
            LocalDateTime expiresAt = LocalDateTime.ofInstant(
                expirationDate.toInstant(), 
                java.time.ZoneId.systemDefault()
            );

            // 6. 构建响应
            AdminAuthDto.AdminLoginResponse response = new AdminAuthDto.AdminLoginResponse();
            response.setAdminId(adminUser.getId());
            response.setUsername(adminUser.getUsername());
            response.setRole(adminUser.getRole());
            response.setRoleName(AdminUser.Role.getRoleName(adminUser.getRole()));
            response.setToken(token);
            response.setExpiresAt(expiresAt);
            response.setPermissions(AdminAuthDto.Permissions.getPermissionsByRole(adminUser.getRole()));

            log.info("管理员登录成功：username={}, role={}", request.getUsername(), adminUser.getRole());
            return ApiResponse.success(response);

        } catch (Exception e) {
            log.error("管理员登录失败", e);
            return ApiResponse.error("管理员登录失败：" + e.getMessage());
        }
    }

    @Override
    public ApiResponse<AdminAuthDto.AdminInfoResponse> getAdminInfo(Long adminId) {
        try {
            // 1. 查询管理员用户
            AdminUser adminUser = adminUserMapper.selectById(adminId);
            if (adminUser == null) {
                return ApiResponse.error(404, "管理员用户不存在");
            }

            // 2. 构建响应
            AdminAuthDto.AdminInfoResponse response = new AdminAuthDto.AdminInfoResponse();
            response.setAdminId(adminUser.getId());
            response.setUsername(adminUser.getUsername());
            response.setRole(adminUser.getRole());
            response.setRoleName(AdminUser.Role.getRoleName(adminUser.getRole()));
            response.setCreateTime(adminUser.getCreateTime());
            response.setPermissions(AdminAuthDto.Permissions.getPermissionsByRole(adminUser.getRole()));

            return ApiResponse.success(response);

        } catch (Exception e) {
            log.error("获取管理员信息失败", e);
            return ApiResponse.error("获取管理员信息失败：" + e.getMessage());
        }
    }

    @Override
    public ApiResponse<AdminAuthDto.DashboardResponse> getDashboardData(Long adminId) {
        try {
            log.info("开始获取仪表盘数据，管理员ID: {}", adminId);
            
            // 验证管理员权限
            boolean hasPermission = hasPermission(adminId, "dashboard:read");
            log.info("管理员ID {} 的dashboard:read权限检查结果: {}", adminId, hasPermission);
            
            if (!hasPermission) {
                log.warn("管理员ID {} 权限不足，无法访问仪表盘", adminId);
                return ApiResponse.error(403, "权限不足");
            }

            // 获取今日日期
            LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
            LocalDateTime sevenDaysAgo = today.minusDays(7);

            // 构建仪表盘数据
            AdminAuthDto.DashboardResponse response = new AdminAuthDto.DashboardResponse();

            // 用户统计
            AdminAuthDto.UserStats userStats = new AdminAuthDto.UserStats();
            userStats.setTotalUsers(adminUserMapper.countTotalUsers());
            userStats.setTodayNewUsers(adminUserMapper.countTodayNewUsers(today));
            userStats.setActiveUsers(adminUserMapper.countActiveUsers(sevenDaysAgo));
            userStats.setPaidUsers(adminUserMapper.countPaidUsers());
            response.setUserStats(userStats);

            // 内容统计
            AdminAuthDto.ContentStats contentStats = new AdminAuthDto.ContentStats();
            contentStats.setTotalWorkflows(adminUserMapper.countTotalWorkflows());
            contentStats.setTodayNewWorkflows(adminUserMapper.countTodayNewWorkflows(today));
            contentStats.setTotalVideos(adminUserMapper.countTotalVideos());
            contentStats.setTodayNewVideos(adminUserMapper.countTodayNewVideos(today));
            contentStats.setPendingAuditContent(adminUserMapper.countPendingAuditContent());
            response.setContentStats(contentStats);

            // 财务统计
            AdminAuthDto.FinanceStats financeStats = new AdminAuthDto.FinanceStats();
            financeStats.setTotalRevenue(userBalanceMapper.sumTotalIncome());
            financeStats.setTodayRevenue(userBalanceMapper.sumTodayIncome(today));
            financeStats.setTotalWithdrawn(withdrawRequestMapper.sumApprovedAmount());
            financeStats.setTotalUserBalance(userBalanceMapper.sumTotalBalance());
            response.setFinanceStats(financeStats);

            // 提现审核统计
            AdminAuthDto.WithdrawStats withdrawStats = new AdminAuthDto.WithdrawStats();
            withdrawStats.setPendingCount(withdrawRequestMapper.countByStatus(0));
            withdrawStats.setPendingAmount(withdrawRequestMapper.sumAmountByStatus(0));
            withdrawStats.setTodayApprovedCount(withdrawRequestMapper.countTodayApproved(today));
            withdrawStats.setTodayApprovedAmount(withdrawRequestMapper.sumTodayApprovedAmount(today));
            response.setWithdrawStats(withdrawStats);

            // 今日数据统计
            AdminAuthDto.TodayStats todayStats = new AdminAuthDto.TodayStats();
            todayStats.setNewUsers(userStats.getTodayNewUsers());
            todayStats.setRevenue(financeStats.getTodayRevenue());
            todayStats.setWorkflowCopies(workflowCopyStatMapper.countTodayCopies(today));
            todayStats.setVideoViews(videoViewStatMapper.countTodayViews(today));
            todayStats.setWithdrawRequests(withdrawRequestMapper.countTodayRequests(today));
            response.setTodayStats(todayStats);

            return ApiResponse.success(response);

        } catch (Exception e) {
            log.error("获取仪表盘数据失败", e);
            return ApiResponse.error("获取仪表盘数据失败：" + e.getMessage());
        }
    }

    @Override
    public boolean hasPermission(Long adminId, String permission) {
        try {
            log.debug("检查权限：adminId={}, permission={}", adminId, permission);
            
            AdminUser adminUser = adminUserMapper.selectById(adminId);
            if (adminUser == null) {
                log.warn("管理员不存在：adminId={}", adminId);
                return false;
            }
            
            log.debug("管理员信息：id={}, username={}, role={}", adminUser.getId(), adminUser.getUsername(), adminUser.getRole());

            String[] permissions = AdminAuthDto.Permissions.getPermissionsByRole(adminUser.getRole());
            log.debug("角色{}的权限列表：{}", adminUser.getRole(), Arrays.toString(permissions));
            
            boolean hasPermission = Arrays.asList(permissions).contains(permission);
            log.debug("权限检查结果：{}", hasPermission);
            
            return hasPermission;

        } catch (Exception e) {
            log.warn("验证管理员权限失败：adminId={}, permission={}", adminId, permission, e);
            return false;
        }
    }

    @Override
    public boolean isAdmin(Long adminId) {
        try {
            AdminUser adminUser = adminUserMapper.selectById(adminId);
            return adminUser != null && AdminUser.Role.isAdmin(adminUser.getRole());
        } catch (Exception e) {
            log.warn("检查管理员角色失败：adminId={}", adminId, e);
            return false;
        }
    }

    @Override
    public boolean isStaff(Long adminId) {
        try {
            AdminUser adminUser = adminUserMapper.selectById(adminId);
            return adminUser != null && AdminUser.Role.isStaff(adminUser.getRole());
        } catch (Exception e) {
            log.warn("检查工作人员角色失败：adminId={}", adminId, e);
            return false;
        }
    }

    @Override
    public boolean needsInitialization() {
        try {
            // 如果数据库中没有任何管理员账号，则需要初始化
            return !adminUserMapper.hasAnyAdmin();
        } catch (Exception e) {
            log.warn("检查系统初始化状态失败", e);
            // 出现异常时，为了安全起见，假设不需要初始化
            return false;
        }
    }
} 