package com.ruoyi.web.modules.content.service.impl;

import java.nio.charset.StandardCharsets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.content.constant.MallServiceAgreementConstants;
import com.ruoyi.web.modules.content.domain.BizMallServiceAgreement;
import com.ruoyi.web.modules.content.mapper.BizMallServiceAgreementMapper;
import com.ruoyi.web.modules.content.service.IMallServiceAgreementService;
import com.ruoyi.web.modules.content.support.AgreementContentSupport;
import com.ruoyi.web.modules.content.vo.MallServiceAgreementAppVO;
import com.ruoyi.web.modules.content.vo.MallServiceAgreementConfigVO;
import com.ruoyi.web.modules.content.vo.MallServiceAgreementStatusVO;

/**
 * 商城服务协议服务实现
 */
@Service
public class MallServiceAgreementServiceImpl implements IMallServiceAgreementService
{
    private static final String DICT_YES_NO = "sys_yes_no";

    @Autowired
    private BizMallServiceAgreementMapper agreementMapper;

    @Override
    public MallServiceAgreementConfigVO getConfig()
    {
        return toConfigVo(loadRowOrDefault());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveConfig(BizMallServiceAgreement row, String operator)
    {
        validateSave(row);
        BizMallServiceAgreement existing = agreementMapper.selectById(MallServiceAgreementConstants.CONFIG_ID);
        row.setConfigId(MallServiceAgreementConstants.CONFIG_ID);
        if (existing == null)
        {
            row.setCreateBy(operator);
            if (agreementMapper.insert(row) <= 0)
            {
                throw new ServiceException("保存失败");
            }
        }
        else
        {
            row.setUpdateBy(operator);
            if (agreementMapper.update(row) <= 0)
            {
                throw new ServiceException("保存失败");
            }
        }
    }

    @Override
    public MallServiceAgreementAppVO getForApp()
    {
        MallServiceAgreementAppVO vo = new MallServiceAgreementAppVO();
        if (!isEnabled())
        {
            vo.setEnabled(false);
            vo.setRegistrationOpen(false);
            vo.setRequireAgreementOnLogin(false);
            vo.setMessage(MallServiceAgreementConstants.MSG_REGISTRATION_CLOSED);
            return vo;
        }
        BizMallServiceAgreement row = agreementMapper.selectById(MallServiceAgreementConstants.CONFIG_ID);
        vo.setEnabled(true);
        vo.setRegistrationOpen(true);
        vo.setRequireAgreementOnLogin(true);
        vo.setAgreementTitle(row.getAgreementTitle());
        vo.setVersionLabel(row.getVersionLabel());
        vo.setContent(row.getContent());
        vo.setCheckboxLabel(buildCheckboxLabel(row.getAgreementTitle(), row.getVersionLabel()));
        return vo;
    }

    @Override
    public MallServiceAgreementStatusVO getStatus()
    {
        MallServiceAgreementStatusVO vo = new MallServiceAgreementStatusVO();
        boolean open = isEnabled();
        vo.setRegistrationOpen(open);
        vo.setRequireAgreementOnLogin(open);
        return vo;
    }

    @Override
    public boolean isEnabled()
    {
        BizMallServiceAgreement row = agreementMapper.selectById(MallServiceAgreementConstants.CONFIG_ID);
        if (row == null)
        {
            return false;
        }
        return MallServiceAgreementConstants.ENABLE_YES.equals(row.getEnableFlag())
                && !AgreementContentSupport.isBlankHtml(row.getContent());
    }

    @Override
    public boolean isRegistrationOpen()
    {
        return isEnabled();
    }

    @Override
    public boolean isAgreementRequiredOnLogin()
    {
        return isEnabled();
    }

    @Override
    public void assertAcceptedForRegister(boolean agreementAccepted)
    {
        if (!isRegistrationOpen())
        {
            throw new ServiceException(MallServiceAgreementConstants.MSG_REGISTRATION_CLOSED);
        }
        if (!agreementAccepted)
        {
            throw new ServiceException(MallServiceAgreementConstants.MSG_AGREE_REQUIRED);
        }
    }

    @Override
    public void assertAcceptedForLogin(boolean agreementAccepted)
    {
        if (!isAgreementRequiredOnLogin())
        {
            return;
        }
        if (!agreementAccepted)
        {
            throw new ServiceException(MallServiceAgreementConstants.MSG_AGREE_REQUIRED);
        }
    }

    @Override
    public String buildCheckboxLabel(String agreementTitle, String versionLabel)
    {
        String title = StringUtils.isEmpty(agreementTitle) ? "" : agreementTitle.trim();
        if (StringUtils.isEmpty(versionLabel))
        {
            return "我已阅读并同意《" + title + "》";
        }
        return "我已阅读并同意《" + title + "》（" + versionLabel.trim() + "）";
    }

    void validateSave(BizMallServiceAgreement row)
    {
        if (row == null)
        {
            throw new ServiceException("参数不能为空");
        }
        if (StringUtils.isEmpty(row.getAgreementTitle()) || StringUtils.isEmpty(row.getAgreementTitle().trim()))
        {
            throw new ServiceException(MallServiceAgreementConstants.MSG_TITLE_REQUIRED);
        }
        String title = row.getAgreementTitle().trim();
        if (title.length() > MallServiceAgreementConstants.MAX_TITLE_LENGTH)
        {
            throw new ServiceException("协议标题长度不能超过128个字符");
        }
        row.setAgreementTitle(title);
        if (StringUtils.isNotEmpty(row.getVersionLabel()))
        {
            String version = row.getVersionLabel().trim();
            if (version.length() > MallServiceAgreementConstants.MAX_VERSION_LENGTH)
            {
                throw new ServiceException("协议版本号长度不能超过32个字符");
            }
            row.setVersionLabel(version);
        }
        else
        {
            row.setVersionLabel(null);
        }
        validateEnableFlag(row.getEnableFlag());
        if (row.getContent() != null && row.getContent().getBytes(StandardCharsets.UTF_8).length
                > MallServiceAgreementConstants.MAX_CONTENT_BYTES)
        {
            throw new ServiceException("协议内容超出允许的最大长度");
        }
        if (MallServiceAgreementConstants.ENABLE_YES.equals(row.getEnableFlag()))
        {
            if (AgreementContentSupport.isBlankHtml(row.getContent()))
            {
                if (StringUtils.isEmpty(row.getContent()))
                {
                    throw new ServiceException(MallServiceAgreementConstants.MSG_CONTENT_REQUIRED_WHEN_ENABLED);
                }
                throw new ServiceException(MallServiceAgreementConstants.MSG_CONTENT_BLANK);
            }
        }
    }

    private void validateEnableFlag(String enableFlag)
    {
        if (!MallServiceAgreementConstants.ENABLE_YES.equals(enableFlag)
                && !MallServiceAgreementConstants.ENABLE_NO.equals(enableFlag))
        {
            throw new ServiceException(MallServiceAgreementConstants.MSG_ENABLE_FLAG_INVALID);
        }
    }

    private BizMallServiceAgreement loadRowOrDefault()
    {
        BizMallServiceAgreement row = agreementMapper.selectById(MallServiceAgreementConstants.CONFIG_ID);
        if (row != null)
        {
            return row;
        }
        BizMallServiceAgreement empty = new BizMallServiceAgreement();
        empty.setConfigId(MallServiceAgreementConstants.CONFIG_ID);
        empty.setAgreementTitle("");
        empty.setContent("");
        empty.setEnableFlag(MallServiceAgreementConstants.ENABLE_NO);
        return empty;
    }

    private MallServiceAgreementConfigVO toConfigVo(BizMallServiceAgreement row)
    {
        MallServiceAgreementConfigVO vo = new MallServiceAgreementConfigVO();
        vo.setConfigId(row.getConfigId());
        vo.setAgreementTitle(row.getAgreementTitle());
        vo.setVersionLabel(row.getVersionLabel());
        vo.setContent(row.getContent());
        vo.setEnableFlag(row.getEnableFlag());
        vo.setUpdateBy(row.getUpdateBy());
        vo.setUpdateTime(row.getUpdateTime());
        vo.setEnableFlagLabel(resolveEnableFlagLabel(row.getEnableFlag()));
        return vo;
    }

    private String resolveEnableFlagLabel(String enableFlag)
    {
        try
        {
            String label = DictUtils.getDictLabel(DICT_YES_NO, enableFlag);
            if (StringUtils.isNotEmpty(label))
            {
                return label;
            }
        }
        catch (Exception ignored)
        {
        }
        return MallServiceAgreementConstants.ENABLE_YES.equals(enableFlag) ? "是" : "否";
    }
}
