package com.mosquito.project.sdk;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;

/**
 * 蚊子项目Java SDK
 *
 * 使用示例:
 * <pre>
 * MosquitoClient client = new MosquitoClient("http://localhost:8080", "your-api-key");
 *
 * // 创建活动
 * Activity activity = client.createActivity("New Activity", startTime, endTime);
 *
 * // 获取分享链接
 * String shareUrl = client.getShareUrl(activity.getId(), userId);
 *
 * // 生成海报
 * byte[] posterImage = client.getPosterImage(activity.getId(), userId);
 * String posterHtml = client.getPosterHtml(activity.getId(), userId);
 *
 * // 获取排行榜
 * List&lt;LeaderboardEntry&gt; leaderboard = client.getLeaderboard(activity.getId());
 * </pre>
 */
public class MosquitoClient {

    private final String baseUrl;
    private final String apiKey;
    private final ApiClient apiClient;

    public MosquitoClient(String baseUrl, String apiKey) {
        this.baseUrl = baseUrl.replaceAll("/+$", "");
        this.apiKey = apiKey;
        this.apiClient = new ApiClient(baseUrl, apiKey);
    }

    // ==================== Activity Management ====================

    /**
     * 创建活动
     */
    public Activity createActivity(String name, ZonedDateTime startTime, ZonedDateTime endTime) {
        return apiClient.post("/api/v1/activities", Map.of(
            "name", name,
            "startTime", startTime.toOffsetDateTime().toString(),
            "endTime", endTime.toOffsetDateTime().toString()
        ), Activity.class);
    }

    /**
     * 获取活动信息
     */
    public Activity getActivity(Long activityId) {
        return apiClient.get("/api/v1/activities/" + activityId, Activity.class);
    }

    /**
     * 更新活动
     */
    public Activity updateActivity(Long activityId, String name, ZonedDateTime endTime) {
        return apiClient.put("/api/v1/activities/" + activityId, Map.of(
            "name", name,
            "endTime", endTime.toOffsetDateTime().toString()
        ), Activity.class);
    }

    /**
     * 获取活动统计
     */
    public ActivityStats getActivityStats(Long activityId) {
        return apiClient.get("/api/v1/activities/" + activityId + "/stats", ActivityStats.class);
    }

    // ==================== Share Functions ====================

    /**
     * 生成分享链接
     */
    public String getShareUrl(Long activityId, Long userId) {
        return getShareUrl(activityId, userId, "default");
    }

    /**
     * 使用指定模板生成分享链接
     */
    public String getShareUrl(Long activityId, Long userId, String template) {
        ShortenResponse response = apiClient.get(
            "/api/v1/me/invitation-info?activityId=" + activityId + "&userId=" + userId + "&template=" + template,
            ShortenResponse.class
        );
        return baseUrl + "/" + response.getPath();
    }

    /**
     * 获取分享元数据 (用于社交媒体)
     */
    public ShareMeta getShareMeta(Long activityId, Long userId) {
        return apiClient.get(
            "/api/v1/me/share-meta?activityId=" + activityId + "&userId=" + userId,
            ShareMeta.class
        );
    }

    // ==================== Poster Functions ====================

    /**
     * 获取海报图片 (PNG)
     */
    public byte[] getPosterImage(Long activityId, Long userId) {
        return getPosterImage(activityId, userId, "default");
    }

    /**
     * 使用指定模板获取海报图片
     */
    public byte[] getPosterImage(Long activityId, Long userId, String template) {
        return apiClient.getBytes(
            "/api/v1/me/poster/image?activityId=" + activityId + "&userId=" + userId + "&template=" + template
        );
    }

    /**
     * 获取海报HTML (可用于iframe嵌入)
     */
    public String getPosterHtml(Long activityId, Long userId) {
        return getPosterHtml(activityId, userId, "default");
    }

    /**
     * 使用指定模板获取海报HTML
     */
    public String getPosterHtml(Long activityId, Long userId, String template) {
        return apiClient.getString(
            "/api/v1/me/poster/html?activityId=" + activityId + "&userId=" + userId + "&template=" + template
        );
    }

    /**
     * 获取海报配置
     */
    public PosterConfig getPosterConfig(String template) {
        return apiClient.get(
            "/api/v1/me/poster/config?template=" + template,
            PosterConfig.class
        );
    }

    // ==================== Leaderboard ====================

    /**
     * 获取排行榜
     */
    public List<LeaderboardEntry> getLeaderboard(Long activityId) {
        return apiClient.getList(
            "/api/v1/activities/" + activityId + "/leaderboard",
            LeaderboardEntry.class
        );
    }

    /**
     * 获取排行榜 (分页)
     */
    public List<LeaderboardEntry> getLeaderboard(Long activityId, int page, int size) {
        return apiClient.getList(
            "/api/v1/activities/" + activityId + "/leaderboard?page=" + page + "&size=" + size,
            LeaderboardEntry.class
        );
    }

    /**
     * 导出排行榜CSV
     */
    public String exportLeaderboardCsv(Long activityId) {
        return apiClient.getString("/api/v1/activities/" + activityId + "/leaderboard/export");
    }

    /**
     * 导出排行榜CSV (Top N)
     */
    public String exportLeaderboardCsv(Long activityId, int topN) {
        return apiClient.getString("/api/v1/activities/" + activityId + "/leaderboard/export?topN=" + topN);
    }

    // ==================== Rewards ====================

    /**
     * 获取用户奖励列表
     */
    public List<RewardInfo> getUserRewards(Long activityId, Long userId) {
        return apiClient.getList(
            "/api/v1/me/rewards?activityId=" + activityId + "&userId=" + userId,
            RewardInfo.class
        );
    }

    // ==================== API Key Management ====================

    /**
     * 创建API密钥
     */
    public String createApiKey(Long activityId, String name) {
        CreateApiKeyResponse response = apiClient.post("/api/v1/api-keys",
            Map.of("activityId", activityId, "name", name),
            CreateApiKeyResponse.class
        );
        return response.getApiKey();
    }

    /**
     * 吊销API密钥
     */
    public void revokeApiKey(Long apiKeyId) {
        apiClient.delete("/api/v1/api-keys/" + apiKeyId);
    }

    /**
     * 重新显示API密钥 (需安全保管)
     */
    public String revealApiKey(Long apiKeyId) {
        RevealApiKeyResponse response = apiClient.get(
            "/api/v1/api-keys/" + apiKeyId + "/reveal",
            RevealApiKeyResponse.class
        );
        return response.getApiKey();
    }

    // ==================== Health Check ====================

    /**
     * 健康检查
     */
    public boolean isHealthy() {
        try {
            apiClient.getString("/actuator/health");
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    // ==================== Domain Classes ====================

    public static class Activity {
        private Long id;
        private String name;
        private ZonedDateTime startTime;
        private ZonedDateTime endTime;

        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public ZonedDateTime getStartTime() { return startTime; }
        public void setStartTime(ZonedDateTime startTime) { this.startTime = startTime; }
        public ZonedDateTime getEndTime() { return endTime; }
        public void setEndTime(ZonedDateTime endTime) { this.endTime = endTime; }
    }

    public static class ActivityStats {
        private long totalParticipants;
        private long totalShares;
        private List<DailyStats> daily;

        public long getTotalParticipants() { return totalParticipants; }
        public void setTotalParticipants(long totalParticipants) { this.totalParticipants = totalParticipants; }
        public long getTotalShares() { return totalShares; }
        public void setTotalShares(long totalShares) { this.totalShares = totalShares; }
        public List<DailyStats> getDaily() { return daily; }
        public void setDaily(List<DailyStats> daily) { this.daily = daily; }
    }

    public static class DailyStats {
        private String date;
        private int participants;
        private int shares;
        public String getDate() { return date; }
        public void setDate(String date) { this.date = date; }
        public int getParticipants() { return participants; }
        public void setParticipants(int participants) { this.participants = participants; }
        public int getShares() { return shares; }
        public void setShares(int shares) { this.shares = shares; }
    }

    public static class LeaderboardEntry {
        private Long userId;
        private String userName;
        private int score;

        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        public String getUserName() { return userName; }
        public void setUserName(String userName) { this.userName = userName; }
        public int getScore() { return score; }
        public void setScore(int score) { this.score = score; }
    }

    public static class ShareMeta {
        private String title;
        private String description;
        private String image;
        private String url;

        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getImage() { return image; }
        public void setImage(String image) { this.image = image; }
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
    }

    public static class PosterConfig {
        private String template;
        private String imageUrl;
        private String htmlUrl;

        public String getTemplate() { return template; }
        public void setTemplate(String template) { this.template = template; }
        public String getImageUrl() { return imageUrl; }
        public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; }
        public String getHtmlUrl() { return htmlUrl; }
        public void setHtmlUrl(String htmlUrl) { this.htmlUrl = htmlUrl; }
    }

    public static class RewardInfo {
        private String type;
        private int points;
        private String createdAt;

        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public int getPoints() { return points; }
        public void setPoints(int points) { this.points = points; }
        public String getCreatedAt() { return createdAt; }
        public void setCreatedAt(String createdAt) { this.createdAt = createdAt; }
    }

    public static class ShortenResponse {
        private String code;
        private String path;
        private String originalUrl;

        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getPath() { return path; }
        public void setPath(String path) { this.path = path; }
        public String getOriginalUrl() { return originalUrl; }
        public void setOriginalUrl(String originalUrl) { this.originalUrl = originalUrl; }
    }

    public static class CreateApiKeyResponse {
        private String apiKey;
        public String getApiKey() { return apiKey; }
        public void setApiKey(String apiKey) { this.apiKey = apiKey; }
    }

    public static class RevealApiKeyResponse {
        private String apiKey;
        private String message;
        public String getApiKey() { return apiKey; }
        public void setApiKey(String apiKey) { this.apiKey = apiKey; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }
}
