package com.ruoyi.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.PosStoreOmg;
import com.ruoyi.system.domain.dto.StoreOmgCredentialDto;
import com.ruoyi.system.domain.vo.PosStoreOmgVo;
import com.ruoyi.system.mapper.PosStoreOmgMapper;
import com.ruoyi.system.service.IPosStoreOmgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 门店 OMG 支付凭证 Service 实现（纯 DB）。状态机沿用 009/011：
 * 0 未申请 --apply--> 1 申请中 --enableWithCredentials--> 2 已开通 <--reset--> 1。
 *
 * @author ruoyi
 * @date 2026-07-29
 */
@Service
public class PosStoreOmgServiceImpl implements IPosStoreOmgService {

    private static final int STATUS_NOT_APPLIED = 0;
    private static final int STATUS_APPLYING = 1;
    private static final int STATUS_ENABLED = 2;
    private static final int ENABLED_ON = 1;

    @Autowired
    private PosStoreOmgMapper posStoreOmgMapper;

    @Override
    public PosStoreOmg getEnabledCredential(Long storeId) {
        if (storeId == null) {
            return null;
        }
        return enabledOrNull(posStoreOmgMapper.selectByStoreId(storeId));
    }

    @Override
    public PosStoreOmg getEnabledCredentialByMerchantId(String merchantId) {
        if (StrUtil.isBlank(merchantId)) {
            return null;
        }
        return enabledOrNull(posStoreOmgMapper.selectByMerchantId(merchantId));
    }

    @Override
    public PosStoreOmg getCredentialByMerchantId(String merchantId) {
        if (StrUtil.isBlank(merchantId)) {
            return null;
        }
        PosStoreOmg row = posStoreOmgMapper.selectByMerchantId(merchantId);
        if (row == null || StrUtil.isBlank(row.getHashKey()) || StrUtil.isBlank(row.getHashIv())) {
            return null;
        }
        return row;
    }

    @Override
    public PosStoreOmg getCredentialByMerchantIdAndStoreId(String merchantId, Long storeId) {
        if (StrUtil.isBlank(merchantId) || storeId == null) {
            return null;
        }
        PosStoreOmg row = posStoreOmgMapper.selectByMerchantIdAndStoreId(merchantId, storeId);
        if (row == null || StrUtil.isBlank(row.getHashKey()) || StrUtil.isBlank(row.getHashIv())) {
            return null;
        }
        return row;
    }

    @Override
    public List<PosStoreOmgVo> selectOmgStoreList(PosStoreOmgVo query) {
        return posStoreOmgMapper.selectOmgStoreList(query);
    }

    @Override
    public PosStoreOmgVo selectOmgStoreDetail(Long storeId) {
        PosStoreOmgVo vo = posStoreOmgMapper.selectOmgStoreDetail(storeId);
        if (vo == null) {
            throw new ServiceException("门店不存在");
        }
        return vo;
    }

    @Override
    public int apply(Long storeId) {
        PosStoreOmg row = getOrCreateByStoreId(storeId);
        if (!Integer.valueOf(STATUS_NOT_APPLIED).equals(row.getOmgStatus())) {
            throw new ServiceException("当前状态不允许发起申请");
        }
        row.setOmgStatus(STATUS_APPLYING);
        row.setApplyTime(new Date());
        return saveOrUpdate(row);
    }

    @Override
    public int enableWithCredentials(StoreOmgCredentialDto dto) {
        PosStoreOmg row = getOrCreateByStoreId(dto.getStoreId());
        if (!Integer.valueOf(STATUS_APPLYING).equals(row.getOmgStatus())) {
            throw new ServiceException("当前状态不允许录入凭证");
        }
        row.setMerchantId(dto.getMerchantId());
        row.setHashKey(dto.getHashKey());
        row.setHashIv(dto.getHashIv());
        if (dto.getEnabledPayments() != null) {
            row.setEnabledPayments(dto.getEnabledPayments());
        } else if (StrUtil.isBlank(row.getEnabledPayments())) {
            row.setEnabledPayments("ALL");
        }
        row.setOmgStatus(STATUS_ENABLED);
        row.setIsEnabled(ENABLED_ON);
        row.setApprovedTime(new Date());
        row.setLastVerifyResult("PASS");
        return saveOrUpdate(row);
    }

    @Override
    public int toggleEnable(Long storeId) {
        PosStoreOmg row = getOrCreateByStoreId(storeId);
        if (!Integer.valueOf(STATUS_ENABLED).equals(row.getOmgStatus())) {
            throw new ServiceException("仅已开通门店可停用/恢复");
        }
        int next = Integer.valueOf(ENABLED_ON).equals(row.getIsEnabled()) ? 0 : ENABLED_ON;
        row.setIsEnabled(next);
        return saveOrUpdate(row);
    }

    @Override
    public int reset(Long storeId) {
        PosStoreOmg row = getOrCreateByStoreId(storeId);
        if (row.getId() == null) {
            throw new ServiceException("门店尚未发起 OMG 申请");
        }
        Date now = new Date();
        return posStoreOmgMapper.update(null, Wrappers.<PosStoreOmg>lambdaUpdate()
                .eq(PosStoreOmg::getId, row.getId())
                .set(PosStoreOmg::getOmgStatus, STATUS_APPLYING)
                .set(PosStoreOmg::getIsEnabled, 0)
                .set(PosStoreOmg::getApprovedTime, null)
                .set(PosStoreOmg::getUpdateTime, now)
                .set(PosStoreOmg::getUpdateBy, currentUser()));
    }

    @Override
    public int recordVerifyResult(Long storeId, String result) {
        PosStoreOmg row = getOrCreateByStoreId(storeId);
        row.setLastVerifyResult(truncate(result));
        return saveOrUpdate(row);
    }

    @Override
    public int setEnabledPayments(Long storeId, String payments) {
        PosStoreOmg row = getOrCreateByStoreId(storeId);
        row.setEnabledPayments(StrUtil.isBlank(payments) ? "ALL" : payments);
        return saveOrUpdate(row);
    }

    // ===== 内部辅助 =====

    private PosStoreOmg enabledOrNull(PosStoreOmg row) {
        if (row == null) {
            return null;
        }
        if (!Integer.valueOf(STATUS_ENABLED).equals(row.getOmgStatus())) {
            return null;
        }
        if (!Integer.valueOf(ENABLED_ON).equals(row.getIsEnabled())) {
            return null;
        }
        if (StrUtil.isBlank(row.getMerchantId()) || StrUtil.isBlank(row.getHashKey()) || StrUtil.isBlank(row.getHashIv())) {
            return null;
        }
        return row;
    }

    private PosStoreOmg getOrCreateByStoreId(Long storeId) {
        if (storeId == null) {
            throw new ServiceException("门店不能为空");
        }
        PosStoreOmg row = posStoreOmgMapper.selectByStoreId(storeId);
        if (row == null) {
            row = new PosStoreOmg();
            row.setStoreId(storeId);
            row.setOmgStatus(STATUS_NOT_APPLIED);
            row.setIsEnabled(ENABLED_ON);
            row.setEnabledPayments("ALL");
        }
        return row;
    }

    private int saveOrUpdate(PosStoreOmg row) {
        Date now = new Date();
        String user = currentUser();
        if (row.getId() == null) {
            row.setCreateTime(now);
            row.setUpdateTime(now);
            row.setCreateBy(user);
            row.setUpdateBy(user);
            return posStoreOmgMapper.insert(row);
        }
        row.setUpdateTime(now);
        row.setUpdateBy(user);
        return posStoreOmgMapper.updateById(row);
    }

    private String currentUser() {
        try {
            return SecurityUtils.getUsername();
        } catch (Exception e) {
            return "system";
        }
    }

    private static String truncate(String s) {
        if (s == null) {
            return "";
        }
        return s.length() > 240 ? s.substring(0, 240) : s;
    }
}
