package com.snack.server.module.address.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.snack.server.common.ResultCode;
import com.snack.server.exception.BusinessException;
import com.snack.server.module.address.dto.req.AddressSaveReq;
import com.snack.server.module.address.entity.Address;
import com.snack.server.module.address.mapper.AddressMapper;
import com.snack.server.module.address.service.AddressService;
import com.snack.server.module.address.vo.AddressVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 收货地址业务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AddressServiceImpl implements AddressService {

    /** 单用户最大地址数 */
    private static final int MAX_ADDRESS_PER_USER = 20;

    private final AddressMapper addressMapper;

    // ==================== 查询 ====================

    @Override
    public List<AddressVO> listByCurrentUser() {
        Long userId = StpUtil.getLoginIdAsLong();
        List<Address> list = addressMapper.selectList(
                new LambdaQueryWrapper<Address>()
                        .eq(Address::getUserId, userId)
                        .orderByDesc(Address::getIsDefault)
                        .orderByDesc(Address::getId)
        );
        return list.stream().map(this::toVO).toList();
    }

    @Override
    public AddressVO getDefault() {
        Long userId = StpUtil.getLoginIdAsLong();
        Address addr = addressMapper.selectOne(
                new LambdaQueryWrapper<Address>()
                        .eq(Address::getUserId, userId)
                        .eq(Address::getIsDefault, 1)
                        .last("LIMIT 1")
        );
        return addr == null ? null : toVO(addr);
    }

    @Override
    public AddressVO getById(Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        Address addr = addressMapper.selectOne(
                new LambdaQueryWrapper<Address>()
                        .eq(Address::getId, id)
                        .eq(Address::getUserId, userId) // 只能看自己的
        );
        if (addr == null) {
            throw new BusinessException(1000, "地址不存在或无权访问");
        }
        return toVO(addr);
    }

    @Override
    public Address getEntityById(Long id) {
        return addressMapper.selectById(id);
    }

    // ==================== 创建 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(AddressSaveReq req) {
        Long userId = StpUtil.getLoginIdAsLong();

        // 1. 单用户地址数量限制
        Long count = addressMapper.selectCount(
                new LambdaQueryWrapper<Address>().eq(Address::getUserId, userId)
        );
        if (count >= MAX_ADDRESS_PER_USER) {
            throw new BusinessException(1000, "地址数量已达上限（" + MAX_ADDRESS_PER_USER + "）");
        }

        // 2. 保存
        Address address = new Address();
        BeanUtil.copyProperties(req, address, "id");
        address.setUserId(userId);
        address.setIsDefault(req.getIsDefault() == null ? 0 : req.getIsDefault());

        // 3. 默认地址处理
        if (address.getIsDefault() == 1) {
            addressMapper.clearDefaultByUserId(userId);
        } else {
            // 若用户没有地址，自动设为默认
            if (count == 0) {
                address.setIsDefault(1);
            }
        }
        addressMapper.insert(address);
        log.info("用户 {} 新增地址 id={}", userId, address.getId());
        return address.getId();
    }

    // ==================== 更新 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(AddressSaveReq req) {
        if (req.getId() == null) {
            throw new BusinessException(1000, "ID 不能为空");
        }
        Long userId = StpUtil.getLoginIdAsLong();
        Address existing = addressMapper.selectOne(
                new LambdaQueryWrapper<Address>()
                        .eq(Address::getId, req.getId())
                        .eq(Address::getUserId, userId)
        );
        if (existing == null) {
            throw new BusinessException(1000, "地址不存在或无权访问");
        }

        // 默认地址处理
        Integer isDefault = req.getIsDefault() == null ? 0 : req.getIsDefault();
        if (isDefault == 1 && existing.getIsDefault() == 0) {
            addressMapper.clearDefaultByUserId(userId);
        }

        Address address = new Address();
        BeanUtil.copyProperties(req, address);
        address.setUserId(userId); // 防止被改
        address.setIsDefault(isDefault);
        addressMapper.updateById(address);
        log.info("更新地址 id={}", address.getId());
    }

    // ==================== 删除 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        Address existing = addressMapper.selectOne(
                new LambdaQueryWrapper<Address>()
                        .eq(Address::getId, id)
                        .eq(Address::getUserId, userId)
        );
        if (existing == null) {
            throw new BusinessException(1000, "地址不存在或无权访问");
        }
        addressMapper.deleteById(id);

        // 若删除的是默认地址，自动将剩余地址中最近的一个设为默认
        if (existing.getIsDefault() != null && existing.getIsDefault() == 1) {
            Address next = addressMapper.selectOne(
                    new LambdaQueryWrapper<Address>()
                            .eq(Address::getUserId, userId)
                            .orderByDesc(Address::getId)
                            .last("LIMIT 1")
            );
            if (next != null) {
                next.setIsDefault(1);
                addressMapper.updateById(next);
            }
        }
        log.info("用户 {} 删除地址 id={}", userId, id);
    }

    // ==================== 设为默认 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDefault(Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        Address existing = addressMapper.selectOne(
                new LambdaQueryWrapper<Address>()
                        .eq(Address::getId, id)
                        .eq(Address::getUserId, userId)
        );
        if (existing == null) {
            throw new BusinessException(1000, "地址不存在或无权访问");
        }
        if (existing.getIsDefault() != null && existing.getIsDefault() == 1) {
            return; // 已经是默认
        }
        // 先清掉其他默认，再设自己
        addressMapper.clearDefaultByUserId(userId);
        existing.setIsDefault(1);
        addressMapper.updateById(existing);
        log.info("用户 {} 将地址 id={} 设为默认", userId, id);
    }

    // ==================== 私有方法 ====================

    private AddressVO toVO(Address a) {
        AddressVO vo = new AddressVO();
        BeanUtil.copyProperties(a, vo);
        // 拼接完整地址
        StringBuilder sb = new StringBuilder();
        if (StrUtil.isNotBlank(a.getProvince()))  sb.append(a.getProvince()).append(" ");
        if (StrUtil.isNotBlank(a.getCity()))      sb.append(a.getCity()).append(" ");
        if (StrUtil.isNotBlank(a.getDistrict()))  sb.append(a.getDistrict()).append(" ");
        if (StrUtil.isNotBlank(a.getDetail()))     sb.append(a.getDetail());
        vo.setFullAddress(sb.toString().trim());
        return vo;
    }
}
