package com.jeesharp.business.modules.marketing.coupon.application;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.coupon.api.MemberCouponMobileApi;
import com.jeesharp.business.modules.coupon.entity.MemberCoupon;
import com.jeesharp.business.modules.coupon.vo.CouponDemoVO;
import com.jeesharp.business.modules.coupon.vo.CouponTemplateQueryVO;
import com.jeesharp.business.modules.coupon.vo.MemberCouponInfoVO;
import com.jeesharp.business.modules.coupon.vo.MemberCouponListVO;
import com.jeesharp.business.modules.coupon.vo.MemberCouponQueryVO;
import com.jeesharp.business.modules.marketing.coupon.dto.MarketingCouponReceiveDTO;
import com.jeesharp.business.modules.marketing.coupon.dto.MarketingCouponTenantQueryDTO;
import com.jeesharp.business.modules.marketing.memberTenant.enums.MemberTenantBindStatusEnum;
import com.jeesharp.business.modules.marketing.memberTenant.service.MemberTenantService;
import com.jeesharp.business.modules.marketing.tenant.mapper.MarketingTenantReadMapper;
import com.jeesharp.business.modules.marketing.tenant.vo.MarketingTenantBriefVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * 店铺优惠券 C 端编排：校验入会关系与 tenantCode，委托 coupon-api。
 *
 * @author jeesharp
 * @since 2026-06-25
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class MarketingCouponApplicationService {

    private final MemberCouponMobileApi memberCouponMobileApi;
    private final MemberTenantService memberTenantService;
    private final MarketingTenantReadMapper marketingTenantReadMapper;

    public PageRespVO<CouponDemoVO> pageAvailableCoupons(String memberId, MarketingCouponTenantQueryDTO dto) {
        MarketingTenantBriefVO tenant = requireTenant(dto.getTenantCode());
        assertMemberBound(memberId, tenant.getId());
        CouponTemplateQueryVO query = new CouponTemplateQueryVO();
        query.setPageNo(dto.getPageNo());
        query.setPageSize(dto.getPageSize());
        return memberCouponMobileApi.pageStoreOfflineTemplates(memberId, tenant.getId(), query);
    }

    @Transactional(readOnly = false)
    public Map<String, Object> receiveCoupon(String memberId, MarketingCouponReceiveDTO dto) {
        MarketingTenantBriefVO tenant = requireTenant(dto.getTenantCode());
        assertMemberBound(memberId, tenant.getId());
        return memberCouponMobileApi.receiveStoreOfflineCoupon(memberId, tenant.getId(), dto.getTemplateId());
    }

    public PageRespVO<MemberCouponListVO> pageMyCoupons(String memberId, MarketingCouponTenantQueryDTO dto) {
        MarketingTenantBriefVO tenant = requireTenant(dto.getTenantCode());
        assertMemberBound(memberId, tenant.getId());
        MemberCouponQueryVO query = new MemberCouponQueryVO();
        query.setPageNo(dto.getPageNo());
        query.setPageSize(dto.getPageSize());
        query.setStatus(dto.getStatus());
        Page<MemberCoupon> page = new Page<>(query);
        return memberCouponMobileApi.pageStoreOfflineMyCoupons(memberId, tenant.getId(), page, query);
    }

    public MemberCouponInfoVO getCouponDetail(String memberId, String tenantCode, String memberCouponId) {
        MarketingTenantBriefVO tenant = requireTenant(tenantCode);
        assertMemberBound(memberId, tenant.getId());
        return memberCouponMobileApi.getStoreOfflineMemberCouponInfo(memberId, tenant.getId(), memberCouponId);
    }

    public CouponDemoVO getCouponWalletDetail(String memberId, String tenantCode, String memberCouponId) {
        MarketingTenantBriefVO tenant = requireTenant(tenantCode);
        assertMemberBound(memberId, tenant.getId());
        return memberCouponMobileApi.getStoreOfflineMemberCouponDemo(memberId, tenant.getId(), memberCouponId);
    }

    private MarketingTenantBriefVO requireTenant(String tenantCode) {
        if (StrUtil.isBlank(tenantCode)) {
            throw new BizErrorException("店铺租户编码不能为空");
        }
        MarketingTenantBriefVO tenant = marketingTenantReadMapper.getByTenantCode(tenantCode.trim());
        if (tenant == null) {
            throw new BizErrorException("店铺不存在");
        }
        if (tenant.getStatus() != null && tenant.getStatus() == 0) {
            throw new BizErrorException("店铺已停用");
        }
        return tenant;
    }

    private void assertMemberBound(String memberId, String tenantId) {
        if (StrUtil.isBlank(memberId)) {
            throw new BizErrorException("请先登录");
        }
        var rel = memberTenantService.getByMemberAndTenant(memberId, tenantId);
        if (rel == null || !MemberTenantBindStatusEnum.BOUND.getValue().equals(rel.getBindStatus())) {
            throw new BizErrorException("请先加入该店铺后再领券");
        }
    }
}
