package kutt

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

// Client 是 Kutt API 客户端
// 用于创建和管理短链接
type Client struct {
	apiURL     string       // Kutt API 基础 URL
	apiKey     string       // API 认证密钥
	httpClient *http.Client // HTTP 客户端
}

// NewClient 创建一个新的 Kutt 客户端
//
// 参数:
//   - apiURL: Kutt API 基础 URL (例如: https://kutt.it/api/v2)
//   - apiKey: Kutt API 密钥
//
// 返回:
//   - *Client: Kutt 客户端实例
func NewClient(apiURL, apiKey string) *Client {
	return &Client{
		apiURL: apiURL,
		apiKey: apiKey,
		httpClient: &http.Client{
			Timeout: 10 * time.Second,
		},
	}
}

// CreateLinkRequest 创建短链接的请求参数
type CreateLinkRequest struct {
	Target      string `json:"target"`                // 目标 URL (必填)
	Description string `json:"description,omitempty"` // 链接描述 (可选)
	ExpireIn    string `json:"expire_in,omitempty"`   // 过期时间，例如 "2 days" (可选)
	Password    string `json:"password,omitempty"`    // 访问密码 (可选)
	CustomURL   string `json:"customurl,omitempty"`   // 自定义短链后缀 (可选)
	Reuse       bool   `json:"reuse,omitempty"`       // 如果目标 URL 已存在则复用 (可选)
	Domain      string `json:"domain,omitempty"`      // 自定义域名 (可选)
}

// Link 短链接响应结构
type Link struct {
	ID          string    `json:"id"`          // 链接 UUID
	Address     string    `json:"address"`     // 短链地址后缀
	Banned      bool      `json:"banned"`      // 是否被封禁
	CreatedAt   time.Time `json:"created_at"`  // 创建时间
	Link        string    `json:"link"`        // 完整短链接 URL
	Password    bool      `json:"password"`    // 是否有密码保护
	Target      string    `json:"target"`      // 目标 URL
	Description string    `json:"description"` // 链接描述
	UpdatedAt   time.Time `json:"updated_at"`  // 更新时间
	VisitCount  int       `json:"visit_count"` // 访问次数
}

// ErrorResponse Kutt API 错误响应
type ErrorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message"`
}

// CreateShortLink 创建短链接
//
// 参数:
//   - ctx: 上下文
//   - req: 创建请求参数
//
// 返回:
//   - *Link: 创建的短链接信息
//   - error: 错误信息
func (c *Client) CreateShortLink(ctx context.Context, req *CreateLinkRequest) (*Link, error) {
	// 序列化请求体
	body, err := json.Marshal(req)
	if err != nil {
		return nil, fmt.Errorf("marshal request failed: %w", err)
	}

	// 创建 HTTP 请求
	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, c.apiURL+"/links", bytes.NewReader(body))
	if err != nil {
		return nil, fmt.Errorf("create request failed: %w", err)
	}

	// 设置请求头
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("X-API-KEY", c.apiKey)

	// 发送请求
	resp, err := c.httpClient.Do(httpReq)
	if err != nil {
		return nil, fmt.Errorf("send request failed: %w", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("read response failed: %w", err)
	}

	// 检查响应状态
	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
		var errResp ErrorResponse
		if err := json.Unmarshal(respBody, &errResp); err == nil && errResp.Error != "" {
			return nil, fmt.Errorf("kutt api error: %s - %s", errResp.Error, errResp.Message)
		}
		return nil, fmt.Errorf("kutt api error: status %d, body: %s", resp.StatusCode, string(respBody))
	}

	// 解析响应
	var link Link
	if err := json.Unmarshal(respBody, &link); err != nil {
		return nil, fmt.Errorf("unmarshal response failed: %w", err)
	}

	return &link, nil
}

// CreateInviteShortLink 为邀请码创建短链接
// 这是一个便捷方法，用于生成邀请链接
//
// 参数:
//   - ctx: 上下文
//   - baseURL: 注册页面基础 URL (例如: https://gethifast.net)
//   - inviteCode: 邀请码
//   - domain: 短链接域名 (例如: getsapp.net)，可为空
//
// 返回:
//   - string: 短链接 URL
//   - error: 错误信息
func (c *Client) CreateInviteShortLink(ctx context.Context, baseURL, inviteCode, domain string) (string, error) {
	// 构建目标 URL - 落地页
	// 格式：https://gethifast.net/?ic=邀请码
	targetURL := fmt.Sprintf("%s?ic=%s", baseURL, inviteCode)

	req := &CreateLinkRequest{
		Target:      targetURL,
		Description: fmt.Sprintf("Invite link for code: %s", inviteCode),
		Reuse:       true, // 如果已存在相同目标 URL 则复用
		Domain:      domain,
	}

	link, err := c.CreateShortLink(ctx, req)
	if err != nil {
		return "", err
	}

	// 强制使用 HTTPS
	if strings.HasPrefix(link.Link, "http://") {
		link.Link = strings.Replace(link.Link, "http://", "https://", 1)
	}

	return link.Link, nil
}

// PeriodStats 时间段统计数据
type PeriodStats struct {
	Total int         `json:"total"` // 总访问量
	Views []int       `json:"views"` // 时间序列数据（按天/小时）
	Stats StatsDetail `json:"stats"` // 详细统计
}

// StatsDetail 详细统计信息
type StatsDetail struct {
	Browser  []StatItem `json:"browser"`  // 浏览器分布
	OS       []StatItem `json:"os"`       // 操作系统分布
	Country  []StatItem `json:"country"`  // 国家分布
	Referrer []StatItem `json:"referrer"` // 来源分布
}

// StatItem 统计项
type StatItem struct {
	Name  string `json:"name"`
	Value int    `json:"value"`
}

// LinkStatsResponse 链接详细统计响应
type LinkStatsResponse struct {
	ID         string      `json:"id"`
	Address    string      `json:"address"`
	Link       string      `json:"link"`
	Target     string      `json:"target"`
	VisitCount int         `json:"visit_count"`
	LastDay    PeriodStats `json:"lastDay"`
	LastWeek   PeriodStats `json:"lastWeek"`
	LastMonth  PeriodStats `json:"lastMonth"`
	LastYear   PeriodStats `json:"lastYear"`
}

// GetLinkStats 获取链接的详细统计数据
//
// 参数:
//   - ctx: 上下文
//   - linkID: 链接的 UUID
//
// 返回:
//   - *LinkStatsResponse: 详细统计数据
//   - error: 错误信息
func (c *Client) GetLinkStats(ctx context.Context, linkID string) (*LinkStatsResponse, error) {
	// 创建 HTTP 请求
	url := fmt.Sprintf("%s/links/%s/stats", c.apiURL, linkID)
	httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return nil, fmt.Errorf("create request failed: %w", err)
	}

	// 设置请求头
	httpReq.Header.Set("X-API-KEY", c.apiKey)
	httpReq.Header.Set("Content-Type", "application/json")

	// 发送请求
	resp, err := c.httpClient.Do(httpReq)
	if err != nil {
		return nil, fmt.Errorf("send request failed: %w", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("read response failed: %w", err)
	}

	// 检查响应状态
	if resp.StatusCode != http.StatusOK {
		var errResp ErrorResponse
		if err := json.Unmarshal(respBody, &errResp); err == nil && errResp.Error != "" {
			return nil, fmt.Errorf("kutt api error: %s - %s", errResp.Error, errResp.Message)
		}
		return nil, fmt.Errorf("kutt api error: status %d, body: %s", resp.StatusCode, string(respBody))
	}

	// 解析响应
	var stats LinkStatsResponse
	if err := json.Unmarshal(respBody, &stats); err != nil {
		return nil, fmt.Errorf("unmarshal response failed: %w", err)
	}

	return &stats, nil
}
