package openinstall

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"time"
)

var (
	// OpenInstall 数据接口基础 URL
	apiBaseURL = "https://data.openinstall.com"
)

// Client for OpenInstall API
type Client struct {
	apiKey     string
	httpClient *http.Client
}

// NewClient creates a new OpenInstall client
// apiKey: OpenInstall 数据接口 ApiKey
func NewClient(apiKey string) *Client {
	return &Client{
		apiKey: apiKey,
		httpClient: &http.Client{
			Timeout: 10 * time.Second,
		},
	}
}

// PlatformStats represents statistics for a specific platform
type PlatformStats struct {
	Platform string `json:"platform"`
	Count    int64  `json:"count"` // 下载/安装量
}

// PlatformDownloads 各端下载量统计
type PlatformDownloads struct {
	Total      int64            `json:"total"`      // 总量
	IOS        int64            `json:"ios"`        // iOS
	Android    int64            `json:"android"`    // Android
	Windows    int64            `json:"windows"`    // Windows
	Mac        int64            `json:"mac"`        // Mac
	Comparison *MonthComparison `json:"comparison"` // 环比数据
}

// MonthComparison 月度对比数据
type MonthComparison struct {
	LastMonthTotal int64   `json:"lastMonthTotal"` // 上月总量
	Change         int64   `json:"change"`         // 变化量 (正数=增长, 负数=下降)
	ChangePercent  float64 `json:"changePercent"`  // 变化百分比
}

// APIResponse 通用响应结构
type APIResponse struct {
	Code  int             `json:"code"`
	Error *string         `json:"error"`
	Body  json.RawMessage `json:"body"`
}

// GrowthData 新增安装数据
type GrowthData struct {
	Date       string `json:"date"`
	Visit      int64  `json:"visit"`       // 访问量
	Click      int64  `json:"click"`       // 点击量
	Install    int64  `json:"install"`     // 安装量
	Register   int64  `json:"register"`    // 注册量
	SurviveD1  int64  `json:"survive_d1"`  // 1日留存
	SurviveD7  int64  `json:"survive_d7"`  // 7日留存
	SurviveD30 int64  `json:"survive_d30"` // 30日留存
}

// DistributionData 设备分布数据
type DistributionData struct {
	Key   string `json:"key"`
	Value int64  `json:"value"`
}

// GetPlatformDownloads 获取各端下载量统计（当月数据 + 环比）
func (c *Client) GetPlatformDownloads(ctx context.Context, channel string) (*PlatformDownloads, error) {
	now := time.Now()

	// 当月数据：本月1号到今天
	startOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
	endOfMonth := now

	// 上月数据：上月1号到上月最后一天
	startOfLastMonth := startOfMonth.AddDate(0, -1, 0)
	endOfLastMonth := startOfMonth.AddDate(0, 0, -1)

	// 获取当月各平台数据
	currentMonthData, err := c.getPlatformData(ctx, startOfMonth, endOfMonth, channel)
	if err != nil {
		return nil, fmt.Errorf("failed to get current month data: %w", err)
	}

	// 获取上月各平台数据
	lastMonthData, err := c.getPlatformData(ctx, startOfLastMonth, endOfLastMonth, channel)
	if err != nil {
		return nil, fmt.Errorf("failed to get last month data: %w", err)
	}

	// 计算总量
	currentTotal := currentMonthData.IOS + currentMonthData.Android + currentMonthData.Windows + currentMonthData.Mac
	lastTotal := lastMonthData.IOS + lastMonthData.Android + lastMonthData.Windows + lastMonthData.Mac

	// 计算环比
	change := currentTotal - lastTotal
	changePercent := float64(0)
	if lastTotal > 0 {
		changePercent = (float64(change) / float64(lastTotal)) * 100
	}

	return &PlatformDownloads{
		Total:   currentTotal,
		IOS:     currentMonthData.IOS,
		Android: currentMonthData.Android,
		Windows: currentMonthData.Windows,
		Mac:     currentMonthData.Mac,
		Comparison: &MonthComparison{
			LastMonthTotal: lastTotal,
			Change:         change,
			ChangePercent:  changePercent,
		},
	}, nil
}

// getPlatformData 获取指定时间范围内各平台的数据
func (c *Client) getPlatformData(ctx context.Context, startDate, endDate time.Time, channel string) (*PlatformDownloads, error) {
	result := &PlatformDownloads{}

	// 获取 iOS 数据
	iosData, err := c.getDeviceDistribution(ctx, startDate, endDate, "ios", "total", channel)
	if err != nil {
		return nil, fmt.Errorf("failed to get iOS data: %w", err)
	}
	for _, item := range iosData {
		result.IOS += item.Value
	}

	// 获取 Android 数据
	androidData, err := c.getDeviceDistribution(ctx, startDate, endDate, "android", "total", channel)
	if err != nil {
		return nil, fmt.Errorf("failed to get Android data: %w", err)
	}
	for _, item := range androidData {
		result.Android += item.Value
	}

	// Windows 和 Mac 暂时设为 0 (需要从其他数据源获取)
	result.Windows = 0
	result.Mac = 0

	return result, nil
}

// getDeviceDistribution 获取设备分布数据
func (c *Client) getDeviceDistribution(ctx context.Context, startDate, endDate time.Time, platform, sumBy, channel string) ([]DistributionData, error) {
	apiURL := fmt.Sprintf("%s/data/sum/growth", apiBaseURL)

	params := url.Values{}
	params.Add("apiKey", c.apiKey)
	params.Add("beginDate", startDate.Format("2006-01-02"))
	params.Add("endDate", endDate.Format("2006-01-02"))
	params.Add("platform", platform)
	params.Add("sumBy", sumBy)
	if channel != "" {
		params.Add("channelCode", channel)
	}
	params.Add("excludeDuplication", "0")

	fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode())

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read response: %w", err)
	}

	var apiResp APIResponse
	if err := json.Unmarshal(body, &apiResp); err != nil {
		return nil, fmt.Errorf("failed to parse response: %w", err)
	}

	if apiResp.Code != 0 {
		errMsg := "unknown error"
		if apiResp.Error != nil {
			errMsg = *apiResp.Error
		}
		return nil, fmt.Errorf("API error (code=%d): %s", apiResp.Code, errMsg)
	}

	var distData []DistributionData
	if err := json.Unmarshal(apiResp.Body, &distData); err != nil {
		return nil, fmt.Errorf("failed to parse distribution data: %w", err)
	}

	return distData, nil
}

// GetPlatformStats 获取平台统计数据（兼容旧接口）
func (c *Client) GetPlatformStats(ctx context.Context, startDate, endDate time.Time) ([]PlatformStats, error) {
	// 调用新增安装数据接口
	growthData, err := c.GetGrowthData(ctx, startDate, endDate, "total")
	if err != nil {
		return nil, fmt.Errorf("failed to get growth data: %w", err)
	}

	// 如果没有数据,返回空列表
	if len(growthData) == 0 {
		return []PlatformStats{}, nil
	}

	// 合并所有数据
	var totalVisits, totalClicks int64
	for _, data := range growthData {
		totalVisits += data.Visit
		totalClicks += data.Click
	}

	return []PlatformStats{
		{
			Platform: "All",
			Count:    totalVisits + totalClicks,
		},
	}, nil
}

// GetGrowthData 获取新增安装数据
func (c *Client) GetGrowthData(ctx context.Context, startDate, endDate time.Time, statType string) ([]GrowthData, error) {
	apiURL := fmt.Sprintf("%s/data/event/growth", apiBaseURL)

	params := url.Values{}
	params.Add("apiKey", c.apiKey)
	params.Add("startDate", startDate.Format("2006-01-02"))
	params.Add("endDate", endDate.Format("2006-01-02"))
	params.Add("statType", statType)

	fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode())

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read response: %w", err)
	}

	var apiResp APIResponse
	if err := json.Unmarshal(body, &apiResp); err != nil {
		return nil, fmt.Errorf("failed to parse response: %w", err)
	}

	if apiResp.Code != 0 {
		errMsg := "unknown error"
		if apiResp.Error != nil {
			errMsg = *apiResp.Error
		}
		return nil, fmt.Errorf("API error (code=%d): %s", apiResp.Code, errMsg)
	}

	var growthData []GrowthData
	if err := json.Unmarshal(apiResp.Body, &growthData); err != nil {
		return nil, fmt.Errorf("failed to parse growth data: %w", err)
	}

	return growthData, nil
}
