package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import shop.alien.entity.store.PlatformShopMembership;
import shop.alien.entity.store.PlatformShopMembershipOrder;
import shop.alien.entity.store.PlatformShopMembershipPlan;
import shop.alien.entity.store.StoreInfo;
import shop.alien.entity.store.vo.PlatformShopMembershipBenefitsVo;
import shop.alien.entity.store.vo.PlatformShopMembershipRemainingDetailVo;
import shop.alien.entity.store.vo.PlatformShopMembershipStatusVo;
import shop.alien.mapper.PlatformShopMembershipMapper;
import shop.alien.mapper.StoreContractMapper;
import shop.alien.mapper.StoreInfoMapper;
import shop.alien.store.service.PlatformShopMembershipOrderService;
import shop.alien.store.service.PlatformShopMembershipPlanService;
import shop.alien.store.service.PlatformShopMembershipService;
import shop.alien.store.service.TrackEventService;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

@Service
@RequiredArgsConstructor
public class PlatformShopMembershipServiceImpl
        extends ServiceImpl<PlatformShopMembershipMapper, PlatformShopMembership>
        implements PlatformShopMembershipService {

    private static final ZoneId CHINA = ZoneId.of("Asia/Shanghai");
    private static final DateTimeFormatter YMD_SLASH = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    private final PlatformShopMembershipOrderService orderService;
    private final PlatformShopMembershipPlanService planService;
    /** 使用 Mapper 而非 StoreInfoService，避免与 StoreInfoServiceImpl 循环依赖 */
    private final StoreInfoMapper storeInfoMapper;
    private final StoreContractMapper storeContractMapper;
    private final TrackEventService trackEventService;

    @Override
    public PlatformShopMembership getByStoreId(Integer storeId) {
        if (storeId == null) {
            return null;
        }
        LambdaQueryWrapper<PlatformShopMembership> w = new LambdaQueryWrapper<>();
        w.eq(PlatformShopMembership::getStoreId, storeId);
        return getOne(w);
    }

    @Override
    public PlatformShopMembershipStatusVo buildStatusVo(Integer storeId) {
        PlatformShopMembershipStatusVo vo = new PlatformShopMembershipStatusVo();
        fillStoreFlags(vo, storeId);
        PlatformShopMembership m = getByStoreId(storeId);
        Date now = new Date();
        if (m == null || m.getExpiryDate() == null) {
            vo.setActive(false);
            vo.setRemainingDays(0);
            vo.setBenefits(buildZeroBenefits());
            return vo;
        }
        vo.setFirstOpenTime(m.getFirstOpenTime());
        vo.setCurrentPeriodStart(m.getCurrentPeriodStart());
        vo.setExpiryDate(m.getExpiryDate());
        boolean active = !m.getExpiryDate().before(now);
        vo.setActive(active);
        if (!active) {
            vo.setRemainingDays(0);
            vo.setBenefits(buildZeroBenefits());
        } else {
            long diffMs = m.getExpiryDate().getTime() - now.getTime();
            int days = (int) Math.max(0, (diffMs + 86400000L - 1) / 86400000L);
            vo.setRemainingDays(days);
            PlatformShopMembershipBenefitsVo benefits = resolveBenefits(m, storeId, m.getExpiryDate());
            vo.setBenefits(benefits != null ? benefits : buildZeroBenefits());
        }
        return vo;
    }

    @Override
    public PlatformShopMembershipRemainingDetailVo buildRemainingDetailVo(Integer storeId) {
        PlatformShopMembershipRemainingDetailVo vo = new PlatformShopMembershipRemainingDetailVo();
        vo.setHasMembershipRecord(false);
        vo.setMembershipActive(false);
        vo.setRemainingDays(0);
        vo.setConsecutivePurchaseTotalDays(null);
        vo.setConsecutivePeriodStartYmd(null);
        vo.setCurrentMembershipEndYmd(null);
        vo.setLastMonthVisitCount(0L);
        vo.setCurrentMonthVisitCount(0L);
        vo.setVisitCountMoMChangePercent(null);
        vo.setWeeklyPromotionTotalPerWeek(0);
        vo.setWeeklyPromotionRemainingThisWeek(0);
        if (storeId == null) {
            return vo;
        }
        fillMonthlyVisitStats(vo, storeId);

        PlatformShopMembership m = getByStoreId(storeId);
        if (m == null || m.getExpiryDate() == null) {
            return vo;
        }
        vo.setHasMembershipRecord(true);
        Date now = new Date();
        Date expiry = m.getExpiryDate();
        vo.setCurrentMembershipEndYmd(formatYmdSlash(expiry));
        boolean active = !expiry.before(now);
        vo.setMembershipActive(active);
        if (active) {
            long diffMs = expiry.getTime() - now.getTime();
            vo.setRemainingDays((int) Math.max(0, (diffMs + 86400000L - 1) / 86400000L));
        } else {
            vo.setRemainingDays(0);
        }
        // 连续续费周期起点：与支付成功写入规则一致；无 current_period_start 时回退首次开通时间
        Date periodStart = m.getCurrentPeriodStart() != null ? m.getCurrentPeriodStart() : m.getFirstOpenTime();
        vo.setConsecutivePeriodStartYmd(formatYmdSlash(periodStart));
        if (periodStart != null && !periodStart.after(expiry)) {
            long spanMs = expiry.getTime() - periodStart.getTime();
            vo.setConsecutivePurchaseTotalDays((int) Math.max(0, (spanMs + 86400000L - 1) / 86400000L));
        }
        fillWeeklyPromotionFields(vo, m, storeId, active);
        return vo;
    }

    private void fillWeeklyPromotionFields(PlatformShopMembershipRemainingDetailVo vo, PlatformShopMembership m,
                                          Integer storeId, boolean active) {
        if (!active) {
            return;
        }
        Integer planId = m.getCurrentPlanId();
        if (planId == null) {
            PlatformShopMembershipOrder ord = orderService.findPaidOrderForCurrentMembershipExpiry(storeId, m.getExpiryDate());
            if (ord != null) {
                planId = ord.getPlanId();
            }
        }
        if (planId != null) {
            PlatformShopMembershipPlan plan = planService.getById(planId);
            if (plan != null && plan.getBenefitWeeklyHomepageSlots() != null) {
                vo.setWeeklyPromotionTotalPerWeek(plan.getBenefitWeeklyHomepageSlots());
            }
        }
        int rem = m.getWeeklyPromotionRemaining() != null ? m.getWeeklyPromotionRemaining() : 0;
        vo.setWeeklyPromotionRemainingThisWeek(rem);
    }

    /** 上月整月 vs 本月至今访问次数及环比（埋点口径） */
    private void fillMonthlyVisitStats(PlatformShopMembershipRemainingDetailVo vo, Integer storeId) {
        ZonedDateTime nowZ = ZonedDateTime.now(CHINA);
        YearMonth thisYm = YearMonth.from(nowZ);
        YearMonth lastYm = thisYm.minusMonths(1);

        ZonedDateTime thisMonthStart = thisYm.atDay(1).atStartOfDay(CHINA);
        ZonedDateTime lastMonthStart = lastYm.atDay(1).atStartOfDay(CHINA);
        ZonedDateTime lastMonthEnd = lastYm.atEndOfMonth().atTime(23, 59, 59, 999_000_000).atZone(CHINA);

        Date lastStart = Date.from(lastMonthStart.toInstant());
        Date lastEnd = Date.from(lastMonthEnd.toInstant());
        long lastCount = trackEventService.countStoreViewEventsBetweenInclusive(storeId, lastStart, lastEnd);
        vo.setLastMonthVisitCount(lastCount);

        Date curStart = Date.from(thisMonthStart.toInstant());
        Date curEnd = Date.from(nowZ.toInstant());
        long curCount = trackEventService.countStoreViewEventsBetweenInclusive(storeId, curStart, curEnd);
        vo.setCurrentMonthVisitCount(curCount);

        if (lastCount > 0) {
            BigDecimal pct = BigDecimal.valueOf(curCount - lastCount)
                    .multiply(BigDecimal.valueOf(100))
                    .divide(BigDecimal.valueOf(lastCount), 2, RoundingMode.HALF_UP);
            vo.setVisitCountMoMChangePercent(pct);
        } else {
            vo.setVisitCountMoMChangePercent(null);
        }
    }

    private static String formatYmdSlash(Date date) {
        if (date == null) {
            return null;
        }
        return date.toInstant().atZone(CHINA).toLocalDate().format(YMD_SLASH);
    }

    private void fillStoreFlags(PlatformShopMembershipStatusVo vo, Integer storeId) {
        if (storeId == null) {
            vo.setSigned(false);
            vo.setSettled(false);
            return;
        }
        StoreInfo storeInfo = storeInfoMapper.selectById(storeId);
        vo.setSigned(isSignedByContract(storeId));
        vo.setSettled(isApproved(storeInfo == null ? null : storeInfo.getStoreApplicationStatus()));
    }

    private boolean isApproved(Integer status) {
        return status != null && status == 1;
    }

    private boolean isSignedByContract(Integer storeId) {
        String signingStatus = storeContractMapper.selectSigningStatus(storeId);
        return "已签署".equals(signingStatus);
    }

    /**
     * 优先使用会员表冗余的 {@link PlatformShopMembership#getCurrentPlanId()}；旧数据为空时回退查已支付订单。
     */
    private PlatformShopMembershipBenefitsVo resolveBenefits(PlatformShopMembership m, Integer storeId, Date membershipExpiry) {
        if (m != null && m.getCurrentPlanId() != null) {
            return buildBenefitsFromPlan(m.getCurrentPlanId(), null);
        }
        PlatformShopMembershipOrder order = orderService.findPaidOrderForCurrentMembershipExpiry(storeId, membershipExpiry);
        if (order == null || order.getPlanId() == null) {
            return null;
        }
        return buildBenefitsFromPlan(order.getPlanId(), order.getPlanName());
    }

    private PlatformShopMembershipBenefitsVo buildBenefitsFromPlan(Integer planId, String planNameWhenPlanMissing) {
        PlatformShopMembershipPlan plan = planService.getById(planId);
        PlatformShopMembershipBenefitsVo b = new PlatformShopMembershipBenefitsVo();
        b.setPlanId(planId);
        b.setPlanName(plan != null ? plan.getPlanName()
                : (planNameWhenPlanMissing != null ? planNameWhenPlanMissing : ""));
        if (plan == null) {
            return b;
        }
        b.setBenefitAdvancedDataAnalysis(plan.getBenefitAdvancedDataAnalysis());
        b.setBenefitMarketingPriority(plan.getBenefitMarketingPriority());
        b.setBenefitFriendCouponManage(plan.getBenefitFriendCouponManage());
        b.setBenefitOrderingManage(plan.getBenefitOrderingManage());
        b.setBenefitFriendRelationManage(plan.getBenefitFriendRelationManage());
        b.setBenefitCommentAppealDelete(plan.getBenefitCommentAppealDelete());
        b.setBenefitOperatingData(plan.getBenefitOperatingData());
        b.setBenefitOperationalActivity(plan.getBenefitOperationalActivity());
        b.setBenefitWeeklyHomepageSlots(plan.getBenefitWeeklyHomepageSlots());
        b.setBenefitMonthlyComputingPower(plan.getBenefitMonthlyComputingPower());
        return b;
    }

    /** 无有效会员或无法解析方案时：权益数值均为 0，方案信息为空 */
    private PlatformShopMembershipBenefitsVo buildZeroBenefits() {
        PlatformShopMembershipBenefitsVo empty = new PlatformShopMembershipBenefitsVo();
        empty.setPlanId(null);
        empty.setPlanName("");
        empty.setBenefitAdvancedDataAnalysis(0);
        empty.setBenefitMarketingPriority(0);
        empty.setBenefitFriendCouponManage(0);
        empty.setBenefitOrderingManage(0);
        empty.setBenefitFriendRelationManage(0);
        empty.setBenefitCommentAppealDelete(0);
        empty.setBenefitOperatingData(0);
        empty.setBenefitOperationalActivity(0);
        empty.setBenefitWeeklyHomepageSlots(0);
        empty.setBenefitMonthlyComputingPower(0);
        return empty;
    }
}
