package com.liquidnet.client.admin.zhengzai.kylin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liquidnet.client.admin.zhengzai.kylin.utils.DataUtils;
import com.liquidnet.commons.lang.util.BeanUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.kylin.dto.param.OrderRefundReasonParam;
import com.liquidnet.service.kylin.dto.param.OrderRefundReasonSearchParam;
import com.liquidnet.service.kylin.dto.vo.OrderRefundReasonVo;
import com.liquidnet.service.kylin.entity.KylinOrderRefundReasons;
import com.liquidnet.service.kylin.mapper.KylinOrderRefundReasonsMapper;
import com.liquidnet.service.kylin.service.admin.IOrderRefundReasonAdminService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 退款原因配置管理
 */
@Slf4j
@Service
public class KylinOrderRefundReasonAdminServiceImpl
        extends ServiceImpl<KylinOrderRefundReasonsMapper, KylinOrderRefundReasons>
        implements IOrderRefundReasonAdminService {

    @Autowired
    private KylinOrderRefundReasonsMapper reasonsMapper;

    @Autowired
    private DataUtils dataUtils;

    @Override
    public Boolean create(OrderRefundReasonParam param) {
        try {
            if (StringUtils.isBlank(param.getName())) {
                return false;
            }
            String reasonId = IDGenerator.nextSnowId();
            LocalDateTime now = LocalDateTime.now();
            KylinOrderRefundReasons entity = param.getFields(reasonId, now);
            // 新建默认未应用
            entity.setIsApplied(0);
            reasonsMapper.insert(entity);
            refreshAppliedCache();
            return true;
        } catch (Exception e) {
            log.error("创建退款原因失败", e);
            return false;
        }
    }

    @Override
    public Boolean update(OrderRefundReasonParam param) {
        try {
            if (StringUtils.isBlank(param.getReasonId()) || StringUtils.isBlank(param.getName())) {
                return false;
            }
            KylinOrderRefundReasons existing = reasonsMapper.selectOne(
                    new QueryWrapper<KylinOrderRefundReasons>().eq("reason_id", param.getReasonId())
            );
            if (existing == null) {
                return false;
            }
            // 应用中不可编辑
            if (existing.getIsApplied() != null && existing.getIsApplied() == 1) {
                return false;
            }
            KylinOrderRefundReasons entity = param.getFields(null, null);
            // 不允许通过 update 直接改应用态
            entity.setIsApplied(null);
            entity.setReasonId(null);
            entity.setCreatedAt(null);
            entity.setUpdatedAt(LocalDateTime.now());
            reasonsMapper.update(entity, new UpdateWrapper<KylinOrderRefundReasons>()
                    .eq("reason_id", param.getReasonId()));
            refreshAppliedCache();
            return true;
        } catch (Exception e) {
            log.error("修改退款原因失败", e);
            return false;
        }
    }

    @Override
    public OrderRefundReasonVo detail(String reasonId) {
        KylinOrderRefundReasons data = reasonsMapper.selectOne(
                new QueryWrapper<KylinOrderRefundReasons>().eq("reason_id", reasonId)
        );
        if (data == null) {
            return null;
        }
        return toVo(data);
    }

    @Override
    public PageInfo<KylinOrderRefundReasons> reasonList(OrderRefundReasonSearchParam param) {
        try {
            PageHelper.startPage(param.getPageNum(), param.getPageSize());
            Map<String, Object> paramMap = BeanUtil.convertBeanToMap(param);
            List<KylinOrderRefundReasons> list = reasonsMapper.searchList(paramMap);
            if (list != null) {
                for (KylinOrderRefundReasons item : list) {
                    item.setIsAppliedName(formatAppliedName(item.getIsApplied()));
                }
            }
            return new PageInfo<>(list);
        } catch (Exception e) {
            log.error("获取退款原因列表失败", e);
            return new PageInfo<>();
        }
    }

    @Override
    public Boolean delete(List<String> reasonIds) {
        try {
            if (reasonIds == null || reasonIds.isEmpty()) {
                return false;
            }
            List<KylinOrderRefundReasons> list = reasonsMapper.selectList(
                    new QueryWrapper<KylinOrderRefundReasons>().in("reason_id", reasonIds)
            );
            for (KylinOrderRefundReasons item : list) {
                if (item.getIsApplied() != null && item.getIsApplied() == 1) {
                    return false;
                }
            }
            reasonsMapper.delete(new QueryWrapper<KylinOrderRefundReasons>().in("reason_id", reasonIds));
            refreshAppliedCache();
            return true;
        } catch (Exception e) {
            log.error("删除退款原因失败", e);
            return false;
        }
    }

    @Override
    public Boolean apply(String reasonId, Integer isApplied) {
        try {
            if (StringUtils.isBlank(reasonId) || isApplied == null || (isApplied != 0 && isApplied != 1)) {
                return false;
            }
            KylinOrderRefundReasons existing = reasonsMapper.selectOne(
                    new QueryWrapper<KylinOrderRefundReasons>().eq("reason_id", reasonId)
            );
            if (existing == null) {
                return false;
            }
            KylinOrderRefundReasons update = new KylinOrderRefundReasons();
            update.setIsApplied(isApplied);
            update.setUpdatedAt(LocalDateTime.now());
            reasonsMapper.update(update, new UpdateWrapper<KylinOrderRefundReasons>().eq("reason_id", reasonId));
            refreshAppliedCache();
            return true;
        } catch (Exception e) {
            log.error("应用/取消应用退款原因失败", e);
            return false;
        }
    }

    @Override
    public List<OrderRefundReasonVo> listApplied() {
        List<OrderRefundReasonVo> cached = dataUtils.getOrderRefundReasonsApplied();
        if (cached != null) {
            return cached;
        }
        return refreshAppliedCache();
    }

    private List<OrderRefundReasonVo> refreshAppliedCache() {
        List<KylinOrderRefundReasons> list = reasonsMapper.listApplied();
        List<OrderRefundReasonVo> voList = new ArrayList<>();
        if (list != null) {
            for (KylinOrderRefundReasons item : list) {
                voList.add(toVo(item));
            }
        }
        dataUtils.setOrderRefundReasonsApplied(voList);
        return voList;
    }

    private OrderRefundReasonVo toVo(KylinOrderRefundReasons data) {
        OrderRefundReasonVo vo = new OrderRefundReasonVo();
        BeanUtils.copyProperties(data, vo);
        vo.setIsAppliedName(formatAppliedName(data.getIsApplied()));
        if (data.getCreatedAt() != null) {
            vo.setCreatedAt(DateUtil.Formatter.yyyyMMddHHmmss.format(data.getCreatedAt()));
        }
        if (data.getUpdatedAt() != null) {
            vo.setUpdatedAt(DateUtil.Formatter.yyyyMMddHHmmss.format(data.getUpdatedAt()));
        }
        return vo;
    }

    private String formatAppliedName(Integer isApplied) {
        if (isApplied != null && isApplied == 1) {
            return "应用中";
        }
        return "未应用";
    }
}
