package com.seer.teach.mall.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.mall.convert.AddressConvert;
import com.seer.teach.mall.entity.AddressEntity;
import com.seer.teach.mall.request.AddressSaveReq;
import com.seer.teach.mall.request.AddressSetDefaultReq;
import com.seer.teach.mall.request.AddressUpdateReq;
import com.seer.teach.mall.response.AddressResp;
import com.seer.teach.mall.mapper.AddressMapper;
import com.seer.teach.mall.service.IAddressService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Captain
 * @since 2025-06-10
 */
@Service
@Slf4j
public class AddressServiceImpl extends ServiceImpl<AddressMapper, AddressEntity> implements IAddressService {

    @Autowired
    private AddressConvert addressConvert;

    /**
     * 查询用户的所有收货地址信息
     *
     * @return
     */
    @Override
    public List<AddressResp> listAddress() {
        //获取当前登录的用户Id
        Integer userId = StpUtil.getLoginIdAsInt();
        List<AddressEntity> list = list(new LambdaQueryWrapper<AddressEntity>()
                .eq(AddressEntity::getUserId, userId)
                .last("LIMIT 50"));
        if(CollectionUtil.isEmpty(list)){
            return Collections.emptyList();
        }
        List<AddressResp> results = new ArrayList<>();
        list.stream().forEach(i->{
            AddressResp addressResp = new AddressResp();
            BeanUtils.copyProperties(i,addressResp);
            results.add(addressResp);
        });
        return results;
    }

    /**
     * 新增收货地址信息
     *
     * @param params
     * @return
     */
    @Override
    public AddressResp saveAddress(AddressSaveReq params) {
        //获取当前登录用户的Id
        Integer userId = StpUtil.getLoginIdAsInt();
        List<AddressEntity> entityList = list(new LambdaQueryWrapper<>(AddressEntity.class).eq(AddressEntity::getUserId, userId));
        if(!CollectionUtil.isEmpty(entityList)){
            AssertUtils.isTrue(entityList.size() < 20,ResultCodeEnum.ADDRESS_CANNOT_EXCEED_20);
            if(params.getIsDefault() == 1){
                Optional<AddressEntity> any = entityList.stream().filter(address -> address.getIsDefault() == 1).findAny();
                any.ifPresent(address -> update(new LambdaUpdateWrapper<>(AddressEntity.class).eq(AddressEntity::getUserId, userId).eq(AddressEntity::getId, address.getId())
                        .set(AddressEntity::getIsDefault, 0)));
            }
        }else{
            params.setIsDefault(1);
        }
        AddressEntity addressEntity = addressConvert.addressSave( params);
        addressEntity.setUserId(userId);
        boolean save = save(addressEntity);
        log.info("用户[{}]新增地址新增结果{}",userId, save);
        return addressConvert.toResp(addressEntity);
    }

    @Override
    public Optional<AddressResp> getAddressByIdIfDefault(Integer id) {
        AddressResp addressById = getAddressById(id);
        if(Objects.nonNull(addressById)){
            return Optional.of(addressById);
        }
        return Optional.ofNullable(getDefaultAddress());
    }

    /**
     * 根据Id查询收货地址信息
     * @param id
     * @return
     */
    @Override
    public AddressResp getAddressById(Integer id) {
        AddressEntity result = getById(id);
        return addressConvert.toResp(result);
    }

    /**
     * 修改收货地址信息
     *
     * @param params
     * @return
     */
    @Override
    public boolean updateAddress(AddressUpdateReq params) {
        //获取当前登录用户的Id
        Integer userId = StpUtil.getLoginIdAsInt();
        AddressEntity addressEntity = getOne(new LambdaQueryWrapper<AddressEntity>()
                .eq(AddressEntity::getId,params.getId())
                .eq(AddressEntity::getUserId,userId));
        AssertUtils.notNull(addressEntity, ResultCodeEnum.NO_TRACKING_SHIPPING_ADDRESS);
        // 如果更新的时候设置未默认收获地址，则需要将原来的默认修改为不默认
        if(Objects.nonNull(params.getIsDefault()) && 1 == params.getIsDefault().intValue()){
            super.update(new LambdaUpdateWrapper<>(AddressEntity.class)
                    .eq(AddressEntity::getUserId,userId)
                    .eq(AddressEntity::getIsDefault,1)
                    .set(AddressEntity::getIsDefault,0));
        }
        BeanUtils.copyProperties(params,addressEntity);
        return updateById(addressEntity);
    }

    /**
     * 根据Id删除收货地址信息
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteAddress(Integer id) {
        Integer userId = StpUtil.getLoginIdAsInt();
        return remove(new LambdaQueryWrapper<AddressEntity>()
                .eq(AddressEntity::getId, id)
                .eq(AddressEntity::getUserId, userId));
    }

    /**
     * 设置默认地址
     *
     * @param params
     * @return
     */
    @Override
    public boolean setDefaultAddress(AddressSetDefaultReq params) {
        Integer userId = StpUtil.getLoginIdAsInt();
        AddressEntity address = getOne(new LambdaQueryWrapper<AddressEntity>()
                .eq(AddressEntity::getId, params.getId())
                .eq(AddressEntity::getUserId, userId));
        AssertUtils.notNull(address,ResultCodeEnum.NO_TRACKING_SHIPPING_ADDRESS);
        //清除当前用户所有默认地址标记
        LambdaUpdateWrapper<AddressEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AddressEntity::getUserId,userId)
                        .set(AddressEntity::getIsDefault,0);
        update(updateWrapper);
        //设置该地址为默认地址
        address.setIsDefault(1);
        return updateById(address);
    }

    /**
     * 查询默认地址
     *
     * @return
     */
    @Override
    public AddressResp getDefaultAddress() {
        Integer userId = StpUtil.getLoginIdAsInt();
        AddressEntity addressEntity = getOne(new LambdaQueryWrapper<AddressEntity>()
                .eq(AddressEntity::getIsDefault, 1)
                .eq(AddressEntity::getUserId, userId));
        AssertUtils.notNull(addressEntity,ResultCodeEnum.NO_TRACKING_DEFAULT_SHIPPING_ADDRESS);
        AddressResp addressResp = new AddressResp();
        BeanUtils.copyProperties(addressEntity,addressResp);
        return addressResp;
    }
}
