package com.ruoyi.web.modules.entry.support;

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeanUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.entry.dto.EntryApplyShopDTO;
import com.ruoyi.web.modules.entry.dto.EntryApplySubmitDTO;
import com.ruoyi.web.modules.merchant.constant.MerchantBindConstants;
import com.ruoyi.web.modules.merchant.constant.MerchantConstants;
import com.ruoyi.web.modules.merchant.domain.BizMerchant;
import com.ruoyi.web.modules.merchant.dto.MerchantCreateDTO;
import com.ruoyi.web.modules.store.dto.ShopCreateDTO;

/**
 * 申请单 JSON 与商户/店铺 DTO 映射
 */
public final class EntryApplyFormMapper
{
    private static final ObjectMapper MAPPER = new ObjectMapper();

    private EntryApplyFormMapper()
    {
    }

    public static String toFormJson(EntryApplySubmitDTO dto)
    {
        try
        {
            Map<String, Object> root = new HashMap<>();
            root.put("subject", dto.getSubject());
            root.put("biz", dto.getBiz());
            root.put("shop", dto.getShop());
            root.put("agreementAccepted", Boolean.TRUE.equals(dto.getAgreementAccepted()));
            return MAPPER.writeValueAsString(root);
        }
        catch (Exception e)
        {
            throw new ServiceException("申请表单序列化失败");
        }
    }

    public static ParsedForm parseFormJson(String formJson)
    {
        if (StringUtils.isEmpty(formJson))
        {
            throw new ServiceException("申请表单数据缺失");
        }
        try
        {
            Map<String, Object> root = MAPPER.readValue(formJson, new TypeReference<Map<String, Object>>()
            {
            });
            ParsedForm parsed = new ParsedForm();
            parsed.setSubject(toMerchant(root.get("subject")));
            parsed.setBiz(toMerchant(root.get("biz")));
            parsed.setShop(toShop(root.get("shop")));
            Object accepted = root.get("agreementAccepted");
            parsed.setAgreementAccepted(accepted instanceof Boolean ? (Boolean) accepted
                    : Boolean.parseBoolean(String.valueOf(accepted)));
            return parsed;
        }
        catch (ServiceException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new ServiceException("申请表单解析失败");
        }
    }

    public static BizMerchant toMerchant(BizMerchant subject, BizMerchant biz, String merchantType)
    {
        BizMerchant merchant = new BizMerchant();
        if (subject != null)
        {
            BeanUtils.copyProperties(subject, merchant);
        }
        if (biz != null)
        {
            copyBizFields(biz, merchant);
        }
        merchant.setMerchantType(merchantType);
        return merchant;
    }

    public static BizMerchant toMerchantFromJson(String formJson, String merchantType)
    {
        ParsedForm parsed = parseFormJson(formJson);
        BizMerchant merchant = toMerchant(parsed.getSubject(), parsed.getBiz(), merchantType);
        normalizeAfterMerge(merchant, merchantType, parsed);
        return merchant;
    }

    private static void normalizeAfterMerge(BizMerchant merchant, String merchantType, ParsedForm parsed)
    {
        if (MerchantConstants.TYPE_ENTERPRISE.equals(merchantType))
        {
            if (StringUtils.isEmpty(merchant.getMerchantName()))
            {
                merchant.setMerchantName(merchant.getCompanyName());
            }
            if (StringUtils.isEmpty(merchant.getServicePhone()) && parsed.getShop() != null)
            {
                merchant.setServicePhone(parsed.getShop().getShopPhone());
            }
        }
    }

    public static MerchantCreateDTO toMerchantCreateDTO(BizMerchant merchant, Long memberId)
    {
        MerchantCreateDTO dto = new MerchantCreateDTO();
        BeanUtils.copyProperties(merchant, dto);
        dto.setBindType(MerchantBindConstants.BIND_MEMBER);
        dto.setBindMemberId(memberId);
        return dto;
    }

    public static ShopCreateDTO toShopCreateDTO(String formJson, Long merchantId)
    {
        ParsedForm parsed = parseFormJson(formJson);
        EntryApplyShopDTO shop = parsed.getShop();
        if (shop == null)
        {
            throw new ServiceException("申请中店铺信息缺失");
        }
        ShopCreateDTO dto = new ShopCreateDTO();
        dto.setMerchantId(merchantId);
        dto.setShopName(shop.getShopName());
        dto.setShopAvatar(shop.getShopAvatar());
        dto.setShopPhone(shop.getShopPhone());
        dto.setShopDesc(shop.getShopDesc());
        return dto;
    }

    public static String resolveSubjectLabel(String merchantType, BizMerchant subject)
    {
        if (subject == null)
        {
            return "";
        }
        if (MerchantConstants.TYPE_ENTERPRISE.equals(merchantType))
        {
            return StringUtils.isNotEmpty(subject.getCompanyName()) ? subject.getCompanyName() : subject.getMerchantName();
        }
        return StringUtils.isNotEmpty(subject.getPersonName()) ? subject.getPersonName() : subject.getMerchantName();
    }

    private static BizMerchant toMerchant(Object node)
    {
        if (node == null)
        {
            return null;
        }
        return MAPPER.convertValue(node, BizMerchant.class);
    }

    private static EntryApplyShopDTO toShop(Object node)
    {
        if (node == null)
        {
            return null;
        }
        return MAPPER.convertValue(node, EntryApplyShopDTO.class);
    }

    private static void copyBizFields(BizMerchant source, BizMerchant target)
    {
        copyIfNotEmpty(source.getMerchantName(), target::setMerchantName);
        copyIfNotEmpty(source.getServicePhone(), target::setServicePhone);
        copyIfNotEmpty(source.getBizRegionCode(), target::setBizRegionCode);
        copyIfNotEmpty(source.getBizRegionName(), target::setBizRegionName);
        copyIfNotEmpty(source.getBizDetailAddress(), target::setBizDetailAddress);
        copyIfNotEmpty(source.getBusinessLicense(), target::setBusinessLicense);
    }

    private static void copyIfNotEmpty(String value, java.util.function.Consumer<String> setter)
    {
        if (StringUtils.isNotEmpty(value))
        {
            setter.accept(value);
        }
    }

    public static class ParsedForm
    {
        private BizMerchant subject;

        private BizMerchant biz;

        private EntryApplyShopDTO shop;

        private Boolean agreementAccepted;

        public BizMerchant getSubject()
        {
            return subject;
        }

        public void setSubject(BizMerchant subject)
        {
            this.subject = subject;
        }

        public BizMerchant getBiz()
        {
            return biz;
        }

        public void setBiz(BizMerchant biz)
        {
            this.biz = biz;
        }

        public EntryApplyShopDTO getShop()
        {
            return shop;
        }

        public void setShop(EntryApplyShopDTO shop)
        {
            this.shop = shop;
        }

        public Boolean getAgreementAccepted()
        {
            return agreementAccepted;
        }

        public void setAgreementAccepted(Boolean agreementAccepted)
        {
            this.agreementAccepted = agreementAccepted;
        }
    }
}
