package com.miraclegarden.smsmessage.mmp;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 按 activityId 聚合的红包快照。
 */
public class MmpPacket {
    public String packetId;
    public String title;
    public String sender;
    public String group;
    public String total;
    public String via;
    public String issuedAt;
    public String expiresAt;
    /** TNG activityStatus：ACTIVE / FINISHED / ENDED / CLOSED / CANCELLED … */
    public String status;
    public String updatedAt;
    public boolean finished;
    public int snapshots;
    /** 已领人数（来自 TNG claimedCount，缺省用名单人数） */
    public int claimedCount;
    /** 红包总份数（TNG totalCount） */
    public int totalCount;
    public int claimantCount;
    public double sumClaimed;
    public List<MmpClaim> leaderboard = new ArrayList<>();

    public MmpPacket() {
    }

    public String displayTitle() {
        if (sender != null && !sender.isEmpty()) {
            return sender + " 的红包";
        }
        if (title != null && !title.isEmpty()) {
            return title;
        }
        return "红包";
    }

    public String shortId() {
        if (packetId == null || packetId.isEmpty()) {
            return "-";
        }
        if (packetId.length() >= 8 && packetId.indexOf('-') > 0) {
            return packetId.substring(0, 8);
        }
        return packetId.length() > 16 ? packetId.substring(0, 16) : packetId;
    }

    /** 手气最佳（金额最大）；排行已按金额降序时取首位。 */
    public MmpClaim bestClaim() {
        if (leaderboard == null || leaderboard.isEmpty()) {
            return null;
        }
        MmpClaim best = leaderboard.get(0);
        for (MmpClaim c : leaderboard) {
            if (c != null && c.amount > best.amount) {
                best = c;
            }
        }
        return best;
    }

    /** 手气最差（金额最小）。 */
    public MmpClaim worstClaim() {
        if (leaderboard == null || leaderboard.isEmpty()) {
            return null;
        }
        MmpClaim worst = leaderboard.get(0);
        for (MmpClaim c : leaderboard) {
            if (c != null && c.amount < worst.amount) {
                worst = c;
            }
        }
        return worst;
    }

    public String luckSummaryLine() {
        refreshClosedState();
        MmpClaim best = bestClaim();
        MmpClaim worst = worstClaim();
        boolean closed = finished;
        String hi = closed ? "手气最佳" : "目前最高";
        String lo = closed ? "手气最差" : "目前最低";
        if (best == null) {
            return hi + "：-    " + lo + "：-";
        }
        String bn = best.nickname != null ? best.nickname : "?";
        String ba = best.amountText != null ? best.amountText
                : String.format(Locale.US, "%.2f", best.amount);
        if (worst == null || leaderboard.size() == 1) {
            return hi + "：" + bn + "（" + ba + "）  " + lo + "：-";
        }
        String wn = worst.nickname != null ? worst.nickname : "?";
        String wa = worst.amountText != null ? worst.amountText
                : String.format(Locale.US, "%.2f", worst.amount);
        return hi + "：" + bn + "（" + ba + "）  " + lo + "：" + wn + "（" + wa + "）";
    }

    /** 根据 expire/status/人数 刷新 finished；过期未领完也会标结束 */
    public void refreshClosedState() {
        if (isFullyClaimed()) {
            finished = true;
            return;
        }
        if (finished) {
            return;
        }
        if (isTerminalStatus(status) || isExpirePassed()) {
            finished = true;
        }
    }

    public boolean isExpired() {
        if (isExpirePassed()) {
            return true;
        }
        if (status == null) {
            return false;
        }
        String s = status.toUpperCase(Locale.US);
        return s.contains("EXPIRE") || s.contains("ENDED") || s.contains("CLOSED")
                || s.contains("CANCEL");
    }

    public boolean isFullyClaimed() {
        int claimed = effectiveClaimedCount();
        int total = effectiveTotalCount();
        return total > 0 && claimed >= total;
    }

    public int effectiveClaimedCount() {
        return Math.max(claimedCount, claimantCount);
    }

    public int effectiveTotalCount() {
        return Math.max(0, totalCount);
    }

    /**
     * 优先展示领取进度，过期放后面：
     * 已全部领取 / 已领取 N/M 人 · 已过期
     */
    public String statusLabel() {
        refreshClosedState();
        String progress;
        if (isFullyClaimed()) {
            progress = "已全部领取";
        } else {
            int claimed = effectiveClaimedCount();
            int total = effectiveTotalCount();
            if (total > 0) {
                progress = "已领取 " + claimed + "/" + total + " 人";
            } else if (claimed > 0) {
                progress = "已领取 " + claimed + " 人";
            } else {
                progress = finished ? "未领取" : "领取中";
            }
        }
        if (isExpired() && !isFullyClaimed()) {
            return progress + " · 已过期";
        }
        return progress;
    }

    private boolean isExpirePassed() {
        long ms = parseIssueMs(expiresAt);
        return ms > 0 && System.currentTimeMillis() >= ms;
    }

    private static boolean isTerminalStatus(String status) {
        if (status == null || status.isEmpty()) {
            return false;
        }
        String s = status.toUpperCase(Locale.US);
        return s.contains("FINISH") || s.contains("COMPLETE") || s.contains("EXPIRE")
                || s.contains("ENDED") || s.contains("CLOSED") || s.contains("CANCEL")
                || s.contains("DONE");
    }

    public boolean matchesFilter(String keyword, int statusFilter) {
        return matchesFilter(keyword, statusFilter, 0, 0L, 0L);
    }

    /**
     * @param timeMode 0全部 1近1天 2近3天 3近7天 4自定义
     * @param customFromMs / customToMs 自定义起止（含当天），未用传 0
     */
    public boolean matchesFilter(String keyword, int statusFilter,
                                 int timeMode, long customFromMs, long customToMs) {
        refreshClosedState();
        if (statusFilter == 1 && finished) {
            return false;
        }
        if (statusFilter == 2 && !finished) {
            return false;
        }
        if (!matchesTime(timeMode, customFromMs, customToMs)) {
            return false;
        }
        if (keyword == null || keyword.trim().isEmpty()) {
            return true;
        }
        String q = keyword.trim().toLowerCase(Locale.US);
        if (containsIgnoreCase(packetId, q) || containsIgnoreCase(sender, q)
                || containsIgnoreCase(title, q) || containsIgnoreCase(group, q)
                || containsIgnoreCase(total, q)) {
            return true;
        }
        if (leaderboard != null) {
            for (MmpClaim c : leaderboard) {
                if (c != null && (containsIgnoreCase(c.nickname, q)
                        || containsIgnoreCase(c.userId, q)
                        || containsIgnoreCase(c.poolId, q))) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean matchesTime(int timeMode, long customFromMs, long customToMs) {
        if (timeMode <= 0) {
            return true;
        }
        long ms = parseIssueMs(issuedAt);
        if (ms <= 0) {
            ms = parseIssueMs(updatedAt);
        }
        if (ms <= 0) {
            return false;
        }
        long now = System.currentTimeMillis();
        if (timeMode == 1) {
            return ms >= now - 1L * 24 * 3600 * 1000;
        }
        if (timeMode == 2) {
            return ms >= now - 3L * 24 * 3600 * 1000;
        }
        if (timeMode == 3) {
            return ms >= now - 7L * 24 * 3600 * 1000;
        }
        if (timeMode == 4) {
            if (customFromMs > 0 && ms < customFromMs) {
                return false;
            }
            if (customToMs > 0 && ms > customToMs) {
                return false;
            }
            return true;
        }
        return true;
    }

    /** 解析发放时间：13/07/2026 11:39:15 或 yyyy-MM-dd… */
    public static long parseIssueMs(String text) {
        if (text == null || text.trim().isEmpty()) {
            return 0;
        }
        String s = text.trim();
        try {
            java.text.SimpleDateFormat[] formats = new java.text.SimpleDateFormat[]{
                    new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.US),
                    new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.US),
                    new java.text.SimpleDateFormat("dd/MM/yyyy", Locale.US),
                    new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US),
                    new java.text.SimpleDateFormat("yyyy-MM-dd", Locale.US),
            };
            for (java.text.SimpleDateFormat f : formats) {
                f.setLenient(true);
                try {
                    java.util.Date d = f.parse(s);
                    if (d != null) {
                        return d.getTime();
                    }
                } catch (Exception ignored) {
                }
            }
        } catch (Exception ignored) {
        }
        return 0;
    }

    private static boolean containsIgnoreCase(String hay, String needle) {
        return hay != null && hay.toLowerCase(Locale.US).contains(needle);
    }
}
