package com.haha.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haha.entity.dto.UserQueryDTO;
import com.haha.common.enums.CommonStatus;
import com.haha.common.enums.UserTag;
import com.haha.entity.User;
import com.haha.mapper.UserMapper;
import com.haha.service.AccountService;
import com.haha.service.UserService;
import com.haha.service.UserTagService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserTagService userTagService;
    private final AccountService accountService;
    private final com.haha.mapper.OrderMapper orderMapper;

    @Override
    public User getUserByOpenId(String openId) {
        return lambdaQuery().eq(User::getOpenid, openId).one();
    }

    @Override
    public User getUserByPhone(String phone) {
        return lambdaQuery().eq(User::getPhone, phone).one();
    }

    @Override
    public boolean updateCreditScore(Long userId, Integer score) {
        return lambdaUpdate().eq(User::getId, userId).set(User::getCreditScore, score).update();
    }

    @Override
    public boolean updateBalance(Long userId, BigDecimal amount) {
        return accountService.updateBalance(userId, amount);
    }

    @Override
    public IPage<User> getPage(int page, int pageSize, UserQueryDTO queryDTO) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        
        // 昵称或手机号搜索
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            wrapper.and(w -> w
                .like(User::getNickname, queryDTO.getKeyword())
                .or()
                .like(User::getPhone, queryDTO.getKeyword())
            );
        }
        
        // 状态筛选
        if (queryDTO.getStatus() != null) {
            wrapper.eq(User::getStatus, queryDTO.getStatus());
        }
        
        // 按创建时间倒序
        wrapper.orderByDesc(User::getCreateTime);
        
        Page<User> pageResult = new Page<>(page, pageSize);
        return page(pageResult, wrapper);
    }

    @Override
    public Map<String, Object> getStatistics() {
        Map<String, Object> stats = new HashMap<>();
        
        // 总客户数
        long total = count();
        stats.put("total", total);
        
        // 正常用户数
        long active = lambdaQuery().eq(User::getStatus, CommonStatus.ENABLED.getCode()).count();
        stats.put("active", active);

        // 禁用用户数
        long disabled = lambdaQuery().eq(User::getStatus, CommonStatus.DISABLED.getCode()).count();
        stats.put("disabled", disabled);
        
        // 新增用户数（今日）
        // TODO: 添加今日新增统计
        stats.put("todayNew", 0);
        
        return stats;
    }

    @Override
    public void fillUserLabels(List<User> users) {
        if (users == null || users.isEmpty()) {
            return;
        }

        // 1. 批量计算用户消费标签
        List<Long> userIds = users.stream()
                .map(User::getId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, UserTag> userTagMap = userTagService.batchComputeUserTags(userIds);

        // 2. 批量查询订单统计
        Map<Long, Long> orderCountMap = orderMapper.batchCountAllOrdersByUserIds(userIds)
                .stream()
                .collect(Collectors.toMap(
                        m -> ((Number) m.get("user_id")).longValue(),
                        m -> ((Number) m.get("order_count")).longValue(),
                        (a, b) -> a
                ));
        Map<Long, BigDecimal> spentMap = orderMapper.batchSumPaidAmountByUserIds(userIds)
                .stream()
                .collect(Collectors.toMap(
                        m -> ((Number) m.get("user_id")).longValue(),
                        m -> (BigDecimal) m.get("total_spent"),
                        (a, b) -> a
                ));

        // 3. 逐条填充标签
        for (User user : users) {
            // 用户消费标签
            UserTag tag = userTagMap.get(user.getId());
            if (tag != null) {
                user.setUserTag(tag.getCode());
                user.setUserTagLabel(tag.getDescription());
            }

            // 状态标签
            if (user.getStatus() != null) {
                if (user.getStatus() == CommonStatus.ENABLED.getCode()) {
                    user.setStatusLabel("正常");
                    user.setStatusColor("success");
                } else if (user.getStatus() == CommonStatus.DISABLED.getCode()) {
                    user.setStatusLabel("禁用");
                    user.setStatusColor("danger");
                } else {
                    user.setStatusLabel("未知");
                    user.setStatusColor("info");
                }
            }

            // 订单统计
            user.setTotalOrders(orderCountMap.getOrDefault(user.getId(), 0L));
            user.setTotalSpent(spentMap.getOrDefault(user.getId(), BigDecimal.ZERO));
        }
    }
}
