package com.sqx.modules.address.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.common.validator.ValidatorUtils;
import com.sqx.modules.address.dao.AddressDao;
import com.sqx.modules.address.entity.Address;
import com.sqx.modules.address.entity.InsideAddress;
import com.sqx.modules.address.service.AddressService;
import com.sqx.modules.address.service.InsideAddressService;
import com.sqx.modules.address.validator.FullAddressGroup;
import com.sqx.modules.address.validator.InsideAddressGroup;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
@RequiredArgsConstructor
public class AddressServiceImpl extends ServiceImpl<AddressDao, Address> implements AddressService {

    private final InsideAddressService insideAddressService;
    private final CommonInfoService commonInfoService;

    @Override
    public Result selectAddressList(Long userId, Integer page, Integer limit) {
        CommonInfo insideAddressSetting = commonInfoService.findOne(442);

        boolean insideAddressFlag = false;
        if (ObjectUtil.isNotNull(insideAddressSetting) && StrUtil.equals(insideAddressSetting.getValue(), Constant.YES)) {
            insideAddressFlag = true;
        }

        Page<Address> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(baseMapper.selectAddressList(pages, userId, insideAddressFlag));
        return Result.success().put("data", pageUtils);
    }

    @Transactional
    @Override
    public Result insertAddress(Address address) {
        // 校验地址参数
        validateAddress(address);

        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        address.setCreateTime(format);
        address.setUpdateTime(format);
        address.setDeleteFlag(0);

        // 如果该条地址不是默认地址，则直接添加
        if(address.getAddressDefault()==0){
            baseMapper.insert(address);
            return Result.success();
        }else {
            Address address1 = new Address();
            address1.setAddressDefault(0);
            //先按userId将该用户的所有地址改为非默认
            baseMapper.update(address1, new QueryWrapper<Address>().eq("user_id", address.getUserId()));
            //再添加默认地址
            baseMapper.insert(address);
            return Result.success();
        }

    }

    @Transactional
    @Override
    public Result updateAddress(Address address) {
        // 校验地址参数
        validateAddress(address);

        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        address.setUpdateTime(format);
        //如果该条地址不是默认地址，则直接修改
        if(address.getAddressDefault()==0){
            baseMapper.update(address, new QueryWrapper<Address>().eq("address_id", address.getAddressId()));
        }else {
            Address address1 = new Address();
            address1.setAddressDefault(0);
            //先按userId将该用户的所有地址改为非默认
            baseMapper.update(address1, new QueryWrapper<Address>().eq("user_id", address.getUserId()));
            //再修改
            baseMapper.update(address, new QueryWrapper<Address>().eq("address_id", address.getAddressId()));
        }
        return Result.success();
    }

    @Override
    public Result selectAddressById(Long addressId) {
        Address address = baseMapper.selectById(addressId);
        if(ObjectUtil.isNull(address)){
            throw new SqxException("地址不存在");
        }
        Long insideAddressId = address.getInsideAddressId();
        if (ObjectUtils.isNotEmpty(insideAddressId)) {
            InsideAddress insideAddress = insideAddressService.getById(insideAddressId);
            if (ObjectUtils.isNotEmpty(insideAddress)) {
                address.setStationId(insideAddress.getStationId());
            }
        }
        return Result.success().put("data", address);
    }

    @Override
    public Result deleteAddress(Long addressId) {
        baseMapper.deleteById(addressId);
        return Result.success();
    }

    @Override
    public Result searchAddress(Long userId, Integer page, Integer limit, String impotr) {
        CommonInfo insideAddressSe = commonInfoService.findOne(442);

        Page<Address> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(baseMapper.selectPage(pages, new QueryWrapper<Address>()
                .like("address_detail", impotr)
                .eq("user_id", userId)
                // 开启校内地址，则只查询校内的地址
                .isNotNull(
                    ObjectUtil.isNotNull(insideAddressSe) && StrUtil.equals(Constant.YES, insideAddressSe.getValue()),
                    "inside_address_id"
                )
                .orderByDesc("create_time")));
        return Result.success().put("data", pageUtils);
    }

    /**
     * 校验地址参数
     * @param address 地址参数
     */
    private void validateAddress(Address address) {
        CommonInfo insideAddressSetting = commonInfoService.findOne(442);
        if (ObjectUtil.isNotNull(insideAddressSetting) && StrUtil.equals(insideAddressSetting.getValue(), Constant.YES)) {
            ValidatorUtils.validateEntity(address, InsideAddressGroup.class);
            InsideAddress insideAddress = insideAddressService.getById(address.getInsideAddressId());
            if (ObjectUtil.isNull(insideAddress)) {
                throw new SqxException("无效的内部地址id");
            }

            address.setProvince(insideAddress.getProvince());
            address.setCity(insideAddress.getCity());
            address.setDistrict(insideAddress.getDistrict());
            address.setAddressDetail(insideAddress.getAddressDetail());
            address.setLng(insideAddress.getLng());
            address.setLat(insideAddress.getLat());
        } else {
            ValidatorUtils.validateEntity(address, FullAddressGroup.class);
        }
    }
}
