package com.czg.service.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.account.dto.ShopPayTypeDTO;
import com.czg.exception.CzgException;
import com.czg.sa.StpKit;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.account.entity.ShopPayType;
import com.czg.account.service.ShopPayTypeService;
import com.czg.service.account.mapper.ShopPayTypeMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 店铺支付类型 服务层实现。
 *
 * @author zs
 * @since 2025-02-26
 */
@Service
public class ShopPayTypeServiceImpl extends ServiceImpl<ShopPayTypeMapper, ShopPayType> implements ShopPayTypeService {
    private final ArrayList<ShopPayType> payTypeArrayList = new ArrayList<>() {{
        add(new ShopPayType().setPayType("cash").setPayName("现金").setIcon("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/3/319005ffef734aa6a88d432459fa59d8.png").setSorts(1));
        add(new ShopPayType().setPayType("bank").setPayName("银行卡").setIcon("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/3/98e6199cc61a480b9c63617600b2f2fe.png").setSorts(2));
        add(new ShopPayType().setPayType("scanCode").setPayName("扫码支付").setIcon("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/3/3a344b46638547df81d5857a3c8cac66.png").setSorts(3));
        add(new ShopPayType().setPayType("deposit").setPayName("储值卡").setIcon("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/3/6f778df10ea74142a6cba310c2a19063.png").setSorts(4));
        add(new ShopPayType().setPayType("virtual").setPayName("挂账支付").setIcon("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/3/6f778df10ea74142a6cba310c2a19063.png").setIsShowShortcut(0).setSorts(5));
    }};

    @Override
    public void addInfo(Long shopId) {
        payTypeArrayList.forEach(item -> {
            long count = count(new QueryWrapper().eq(ShopPayType::getShopId, shopId).eq(ShopPayType::getPayType, item.getPayType()));
            if (count > 0) {
                return;
            }
            ShopPayType shopPayType = BeanUtil.copyProperties(item, ShopPayType.class);
            shopPayType.setShopId(shopId);
            save(shopPayType);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSort(Long shopId, Integer payTypeId, Integer targetSort) {
        // 1. 查询当前拖动的项
        ShopPayType current = getById(payTypeId);
        if (current == null) {
            throw new RuntimeException("支付类型不存在");
        }

        Integer oldSort = current.getSorts();
        // 如果位置没变，不处理
        if (oldSort.equals(targetSort)) {
            return;
        }

        // 2. 查询同店铺下所有支付类型（按排序升序）
        QueryWrapper wrapper = QueryWrapper.create()
                .eq(ShopPayType::getShopId, shopId)
                .orderBy(ShopPayType::getSorts, true);

        List<ShopPayType> list = list(wrapper);

        // 3. 重新排序（核心算法）
        for (int i = 0; i < list.size(); i++) {
            ShopPayType item = list.get(i);
            if (item.getId().equals(payTypeId)) {
                // 当前拖动项，设置目标排序
                item.setSorts(targetSort);
            } else if (oldSort < targetSort) {
                // 向下拖动：原排序 < 目标排序 → 中间项排序 -1
                if (item.getSorts() > oldSort && item.getSorts() <= targetSort) {
                    item.setSorts(item.getSorts() - 1);
                }
            } else {
                // 向上拖动：原排序 > 目标排序 → 中间项排序 +1
                if (item.getSorts() < oldSort && item.getSorts() >= targetSort) {
                    item.setSorts(item.getSorts() + 1);
                }
            }
        }
        // 4. 批量更新排序
        updateBatch(list);
    }

    @Override
    public List<ShopPayType> getList(Long shopId) {
        List<ShopPayType> list = list(new QueryWrapper().eq(ShopPayType::getShopId, StpKit.USER.getShopId()).orderBy(ShopPayType::getSorts, true));
        if (list.isEmpty()) {
            addInfo(shopId);
            list = list(new QueryWrapper().eq(ShopPayType::getShopId, StpKit.USER.getShopId()).orderBy(ShopPayType::getSorts, true));
        }
        return list;
    }

    @Override
    public Boolean add(Long shopId, ShopPayType shopPayType) {
        long count = count(new QueryWrapper().eq(ShopPayType::getShopId, shopId).and(r -> {
            r.eq(ShopPayType::getPayType, shopPayType.getPayType()).or(r1 -> {
                r1.eq(ShopPayType::getPayName, shopPayType.getPayName());
            });
        }));
        if (count > 0) {
            throw new CzgException("支付方式或支付名称已存在");
        }

        ShopPayType payType = BeanUtil.copyProperties(shopPayType, ShopPayType.class);
        payType.setShopId(shopId);
        return save(payType);
    }

    @Override
    public Boolean edit(Long shopId, ShopPayTypeDTO shopPayTypeDTO) {
        ShopPayType shopPayType = BeanUtil.copyProperties(shopPayTypeDTO, ShopPayType.class);
        if (StrUtil.isNotBlank(shopPayTypeDTO.getPayName())) {
            long count = count(new QueryWrapper().eq(ShopPayType::getShopId, shopId)
                    .eq(ShopPayType::getPayName, shopPayTypeDTO.getPayName())
                    .ne(ShopPayType::getId, shopPayTypeDTO.getId()));
            if (count > 0) {
                throw new CzgException("支付名称已存在");
            }
        }

        if (StrUtil.isNotBlank(shopPayTypeDTO.getPayType())) {
            long count = count(new QueryWrapper().eq(ShopPayType::getShopId, shopId)
                    .eq(ShopPayType::getPayType, shopPayTypeDTO.getPayType())
                    .ne(ShopPayType::getId, shopPayTypeDTO.getId()));
            if (count > 0) {
                throw new CzgException("支付方式已存在");
            }
        }

        return update(shopPayType, new QueryWrapper().eq(ShopPayType::getId, shopPayTypeDTO.getId()).eq(ShopPayType::getShopId, shopId));
    }
}
