package com.bjtdba.userCenter.service.impl;

import com.bjtdba.entity.order.User;
import com.bjtdba.entity.userCenter.UserBill;
import com.bjtdba.userCenter.dao.*;
import com.bjtdba.userCenter.dto.request.*;
import com.bjtdba.userCenter.dto.response.UserContributeModifyResponse;
import com.bjtdba.userCenter.dto.request.GetUserListRequest;
import com.bjtdba.userCenter.dto.request.ModifyPVRequest;
import com.bjtdba.userCenter.dto.request.UserScoreModifyRequest;
import com.bjtdba.userCenter.dto.response.ModifyPVResponse;
import com.bjtdba.userCenter.dto.response.UserScoreModifyResponse;
import com.bjtdba.userCenter.dto.response.common.PageResult;
import com.bjtdba.userCenter.dto.response.UserDTO;
import com.bjtdba.userCenter.entity.UserEntity;
import com.bjtdba.userCenter.entity.UserPvLogEntity;
import com.bjtdba.userCenter.entity.UserSignGongxianEntity;
import com.bjtdba.userCenter.entity.UserSignScoreEntity;
import com.bjtdba.userCenter.exception.BusinessException;
import com.bjtdba.userCenter.service.UserService;
import com.bjtdba.userCenter.util.PasswordUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service("userService")
@RequiredArgsConstructor
public class UserServiceImpl  implements UserService {
    @Autowired
    private UserInfoDao userInfoDao;
    @Autowired
    private MerchantDao merchantDao;
    @Autowired
    private UserBillDao userBillDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserPvLogDao userPvLogDao;
    @Autowired
    private UserSignScoreDao userSignScoreDao;
    @Autowired
    private UserSignGongxianDao userSignGongxianDao;
    @Autowired
    private HttpServletRequest httpServletRequest;



    public User queryByid(Integer uid){
        return  userInfoDao.queryByid(uid);
    }

    @Override
    public Integer dachangType(Integer uid) {
        return userInfoDao.dachangType(uid);
    }

    @Override
    public Double getoffLine(Integer uid){
        return merchantDao.getoffLine(uid);
    }

    public Integer getoffLineCount(Integer uid){
        return merchantDao.getoffLineCount(uid);
    }

    public List<UserBill> getUserBillList(UserBill userBill){
        return userBillDao.getUserBillList(userBill);
    }

    public Integer getUserBillCount(UserBill userBill){
        return userBillDao.getUserBillCount(userBill);
    }

    public BigDecimal getUserCommission(Integer uid){
        return  userBillDao.getUserCommission(uid);
    }

    @Override
    public PageResult<UserDTO> getUserList(GetUserListRequest request) {

        // 查询数据
        List<UserEntity> userEntityList = userDao.getUserList(
                request.getAccount(),
                request.getNickname(),
                request.getUid(),
                request.getStatus(),
                request.getOffset(),
                request.getPageSize()
        );

        // 转换DTO
        List<UserDTO> dtoList = convertToDTOList(userEntityList);

        // 查询总数
        long total = userDao.getUserListCount(
                request.getAccount(),
                request.getNickname(),
                request.getUid(),
                request.getStatus()
        );

        return new PageResult<>(
                dtoList,
                request.getPageNum(),
                request.getPageSize(),
                total
        );
    }

    private List<UserDTO> convertToDTOList(List<UserEntity> userEntityList) {
        if (CollectionUtils.isEmpty(userEntityList)) {
            return Collections.emptyList();
        }
        return userEntityList.stream()
                .map(this::convertToUserDTO)
                .collect(Collectors.toList());
    }

    private UserDTO convertToUserDTO(UserEntity userEntity) {
        UserDTO dto = new UserDTO();
        dto.setUid(userEntity.getUid());
        dto.setAccount(userEntity.getAccount());
        dto.setRealName(userEntity.getRealName());
        dto.setNickname(userEntity.getNickname());
        dto.setSex(userEntity.getSex());
        dto.setSpreadUid(userEntity.getSpreadUid());
        dto.setAvatar(userEntity.getAvatar());
        dto.setPhone(userEntity.getPhone());
        dto.setScore(userEntity.getScore());
        dto.setBrokeragePrice(userEntity.getBrokeragePrice());
        dto.setRepurchasePrice(userEntity.getRepurchasePrice());
        dto.setStatus(userEntity.getStatus());
        dto.setCreateTime(userEntity.getCreateTime());
        dto.setExternal(userEntity.getExternal());
        dto.setExternalId(userEntity.getExternalId());
        dto.setLevelId(userEntity.getLevelId());
        dto.setUserGroup(userEntity.getUserGroup());
        dto.setContribute(userEntity.getContribute());
        dto.setJingdou(userEntity.getJingdou());
        dto.setVr(userEntity.getVr());
        dto.setPv(userEntity.getPv());
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserScoreModifyResponse modifyUserScore(UserScoreModifyRequest request) {
        // 1. 获取用户并加锁
        UserEntity userEntity = userDao.getUserInfoByUidForUpdate(request.getUid());
        if (userEntity == null) {
            throw BusinessException.userNotFound();
        }

        // 2. 积分操作处理
        BigDecimal newScore;
        if (request.getPm() == 1) {  // 收入
            newScore = userEntity.getScore().add(request.getRewardScore());
        } else {  // 支出
            if (userEntity.getScore().compareTo(request.getRewardScore()) < 0) {
                throw BusinessException.insufficientScore();
            }
            newScore = userEntity.getScore().subtract(request.getRewardScore());
        }

        // 3. 更新用户积分（带乐观锁）
        int updateCount = userDao.updateUserScore(
                request.getUid(),
                newScore
        );
        if (updateCount == 0) {
            throw BusinessException.updateScoreFailed();
        }

        // 4. 创建积分记录
        UserSignScoreEntity record = buildScoreRecord(request, newScore);
        userSignScoreDao.insertByEntity(record);

        // 5. 构建响应
        return UserScoreModifyResponse.builder()
                .uid(request.getUid())
                .currentScore(newScore)
                .transactionId(record.getId().toString())
                .build();
    }


    private UserSignScoreEntity buildScoreRecord(UserScoreModifyRequest request, BigDecimal currentScore) {
        UserSignScoreEntity record = new UserSignScoreEntity();
        record.setUid(request.getUid());
        record.setRewardScore(request.getRewardScore());
        record.setPm(request.getPm());
        record.setOrderId(request.getOrderId());
        record.setOrderType(request.getOrderType());
        record.setSurplus(currentScore);
        record.setAddtime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
        record.setMark(buildRecordMark(request));
        return record;
    }

    private String buildRecordMark(UserScoreModifyRequest request) {
        return String.format("%s积分，订单号：%s",
                request.getPm() == 1 ? "收入" : "支出",
                request.getOrderId());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserContributeModifyResponse modifyUserContribute(UserContributeModifyRequest request) {
        // 1. 获取用户并加锁
        UserEntity userEntity = userDao.getUserInfoByUidForUpdate(request.getUid());
        if (userEntity == null) {
            throw BusinessException.userNotFound();
        }

        // 2. 贡献值操作处理
        BigDecimal newContribute;
        if (request.getType() == 1) {  // 赠送
            newContribute = userEntity.getContribute().add(request.getNumber());
        } else {  // 消耗
            if (userEntity.getContribute().compareTo(request.getNumber()) < 0) {
                throw BusinessException.insufficientContribute();
            }
            newContribute = userEntity.getScore().subtract(request.getNumber());
        }

        // 3. 更新用户贡献值（带乐观锁）
        int updateCount = userDao.updateUserContribute(
                request.getUid(),
                newContribute
        );
        if (updateCount == 0) {
            throw BusinessException.updateContributeFailed();
        }

        // 4. 创建贡献值记录
        UserSignGongxianEntity record = buildContributeRecord(request, newContribute);
        int createResult = userSignGongxianDao.insertByEntity(record);
        if (createResult == 0) {
            throw BusinessException.createContributeFailed();
        }

        // 5. 构建响应
        return UserContributeModifyResponse.builder()
                .uid(request.getUid())
                .currentContribute(newContribute)
                .transactionId(record.getId().toString())
                .build();
    }

    private UserSignGongxianEntity buildContributeRecord(UserContributeModifyRequest request, BigDecimal newContribute) {
        UserSignGongxianEntity record = new UserSignGongxianEntity();
        record.setUid(request.getUid());
        record.setMerId(request.getMerId());
        record.setNumber(request.getNumber());
        record.setStatus(request.getStatus());
        record.setMark(buildContributeMark(request));
        record.setDesc(request.getDesc());
        record.setOrderId(request.getOrderId());
        record.setOrderType(request.getOrderType());
        record.setSurplus(newContribute);
        record.setType(request.getType());
        if (request.getStatus() == 1) {
            record.setSettlementTime(Timestamp.valueOf(LocalDateTime.now()));
        }
        record.setAddtime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
        return record;
    }

    private String buildContributeMark(UserContributeModifyRequest request) {
        return String.format("%s贡献值，订单号：%s",
                request.getType() == 1 ? "收入" : "支出",
                request.getOrderId());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO createUserInfo(CreateUserInfoRequest request) {
        // 1. 获取用户并加锁
        UserEntity userEntity = userDao.getUserInfoByAccount(request.getAccount());
        if (userEntity != null) {
            throw BusinessException.userIsExist();
        }
        userEntity = new UserEntity();
        userEntity.setAccount(request.getAccount());
        userEntity.setPhone(request.getPhone());
        userEntity.setPwd(PasswordUtil.hashPassword("123456"));
        userEntity.setNickname(request.getNickname());
        userEntity.setRealName(request.getRealName());
        userEntity.setAvatar("https://cdn.bjtdba.com/vod/image/2025-01-20/20250120125206881.png");
        userEntity.setSpreadUid(request.getSpreadUid());
        userEntity.setSex(request.getSex());
        userEntity.setExternal(request.getExternal());
        userEntity.setExternalId(request.getExternalId());
        userEntity.setLevelId(request.getLevelId());
        // 设置系统默认值
        userEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
        userEntity.setLastTime(new Timestamp(System.currentTimeMillis()));
        userEntity.setLastIp(request.getLastIp());
        userEntity.setStatus(1); // 默认状态：正常
        userEntity.setIsDel(0); // 未删除
        userEntity.setScore(BigDecimal.ZERO); // 默认积分
        userEntity.setUserType(httpServletRequest.getHeader("X-API-KEY"));
        int uid = userDao.insertUserByUserEntity(userEntity);
        if (uid <= 0) {
            throw BusinessException.createUserFailed();
        }
        return convertToUserDTO(userEntity);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO updateUserInfo(UpdateUserInfoRequest request) {
        // 1. 获取用户并加锁
        UserEntity userEntity = userDao.getUserInfoByUidForUpdate(request.getUid());
        if (userEntity == null) {
            // 如果用户不存在则创建
            throw BusinessException.userNotFound();
        }
        UserEntity userEntityByAccount = userDao.getUserInfoByAccount(request.getAccount());
        if (userEntityByAccount != null && !userEntityByAccount.getUid().equals(request.getUid())) {
            throw BusinessException.userAccountIsExist();
        }
        // 只更新非空字段（根据业务需求调整）
        if (request.getAccount() != null) {
            userEntity.setAccount(request.getAccount());
        }
        if (request.getPhone() != null) {
            userEntity.setPhone(request.getPhone());
        }
        if (request.getNickname() != null) {
            userEntity.setNickname(request.getNickname());
        }
        if (request.getRealName() != null) {
            userEntity.setRealName(request.getRealName());
        }
        if (request.getAvatar() != null) {
            userEntity.setAvatar(request.getAvatar());
        }
        if (request.getSpreadUid() != null) {
            userEntity.setSpreadUid(request.getSpreadUid());
        }
        if (request.getSex() != null) {
            userEntity.setSex(request.getSex());
        }
        if (request.getLevelId() != null) {
            userEntity.setLevelId(request.getLevelId());
        }
        // 更新最后活跃时间
        userEntity.setLastTime(new Timestamp(System.currentTimeMillis()));
        // 执行更新操作
        int updateCount = userDao.updateUserByUid(userEntity);
        if (updateCount <= 0) {
            throw BusinessException.updateUserFailed();
        }
        return convertToUserDTO(userEntity);
    }

    @Override
    public ModifyPVResponse modifyUserPV(ModifyPVRequest request) {
        UserPvLogEntity record = buildModifyPVRecord(request);
        record.setAddtime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
        userPvLogDao.insertByEntity(record);

        return ModifyPVResponse.builder()
                .id(record.getId())
                .uid(record.getUid())
                .orderId(record.getOrderId())
                .pv(record.getPv())
                .status(record.getStatus())
                .mark(record.getMark())
                .orderType(record.getOrderType())
                .settlementTime(record.getSettlementTime())
                .build();
    }
        private UserPvLogEntity buildModifyPVRecord(ModifyPVRequest request) {
            UserPvLogEntity record = new UserPvLogEntity();
            record.setUid(request.getUid());
            record.setPv(request.getPv());
            record.setStatus(request.getStatus());
            record.setMark(request.getMark());
            record.setOrderId(request.getOrderId());
            record.setOrderType(request.getOrderType());
            if (request.getStatus() == 1) {
                record.setSettlementTime(Timestamp.valueOf(LocalDateTime.now()));
            }
            return record;
    }
}
