package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
)

const (
	BaseURL = "http://localhost:9991"
	Token   = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidXNlcm5hbWUiOiJTdXBlciIsIm5pY2tuYW1lIjoiU3VwZXIiLCJpc19zdXBlciI6MSwicGxhdGZvcm0iOiLnrqHnkIbnq68iLCJleHAiOjE3NjU2NDIwMDYsIm5iZiI6MTc2NTM4MjgwNiwiaWF0IjoxNzY1MzgyODA2fQ.1pYRmSmFd-b4PudiYhGXgCv-LBr49_MMfNdyuc_7LXA"
)

func main() {
	if len(os.Args) > 1 && os.Args[1] == "check-json" {
		CheckAPIJSONTags()
		return
	}

	fmt.Println("Starting to setup complete task center...")

	// 1. 清理现有任务
	tasks := doRequest("GET", "/api/admin/task-center/tasks", nil)
	list := tasks["list"].([]interface{})
	for _, t := range list {
		task := t.(map[string]any)
		id := int64(task["id"].(float64))
		fmt.Printf("Deleting existing task: %d - %s\n", id, task["name"])
		doRequest("DELETE", fmt.Sprintf("/api/admin/task-center/tasks/%d", id), nil)
	}

	// ---------------------------------------------------------
	// 任务 1: 每日订单挑战 (Daily Order Challenge)
	// ---------------------------------------------------------
	t1ID := createTask("每日订单挑战", "每日完成订单挑战，赢取积分与道具", 1, 1)
	upsertTiers(t1ID, []map[string]any{
		{"metric": "order_count", "operator": ">=", "threshold": 1, "window": "daily", "repeatable": 1, "priority": 1},
		{"metric": "order_count", "operator": ">=", "threshold": 10, "window": "daily", "repeatable": 1, "priority": 2},
		{"metric": "order_count", "operator": ">=", "threshold": 100, "window": "daily", "repeatable": 1, "priority": 3},
	})
	// 获取 Tier IDs 并配置奖励
	t1Tiers := listTiers(t1ID)
	var r1 []map[string]any
	for _, t := range t1Tiers {
		p := int(t["Priority"].(float64))
		tid := int64(t["ID"].(float64))
		if p == 1 { // 1单 -> 1元(100积分)
			r1 = append(r1, map[string]any{"tier_id": tid, "reward_type": "points", "reward_payload": map[string]int{"points": 100}, "quantity": 1})
		} else if p == 2 { // 10单 -> 优惠券ID 1
			r1 = append(r1, map[string]any{"tier_id": tid, "reward_type": "coupon", "reward_payload": map[string]int{"coupon_id": 1}, "quantity": 1})
		} else if p == 3 { // 100单 -> 道具卡ID 1
			r1 = append(r1, map[string]any{"tier_id": tid, "reward_type": "item_card", "reward_payload": map[string]int{"card_id": 1, "quantity": 1}, "quantity": 1})
		}
	}
	upsertRewards(t1ID, r1)
	fmt.Printf("Created Task [Daily Order]: %d\n", t1ID)

	// ---------------------------------------------------------
	// 任务 2: 每日邀请挑战 (Daily Invite Challenge)
	// ---------------------------------------------------------
	t2ID := createTask("每日邀请挑战", "每日邀请好友，奖励领不停", 1, 1)
	upsertTiers(t2ID, []map[string]any{
		{"metric": "invite_count", "operator": ">=", "threshold": 1, "window": "daily", "repeatable": 1, "priority": 1},
		{"metric": "invite_count", "operator": ">=", "threshold": 10, "window": "daily", "repeatable": 1, "priority": 2},
		{"metric": "invite_count", "operator": ">=", "threshold": 100, "window": "daily", "repeatable": 1, "priority": 3},
	})
	t2Tiers := listTiers(t2ID)
	var r2 []map[string]any
	for _, t := range t2Tiers {
		p := int(t["Priority"].(float64))
		tid := int64(t["ID"].(float64))
		if p == 1 { // 1人 -> 1元(100积分)
			r2 = append(r2, map[string]any{"tier_id": tid, "reward_type": "points", "reward_payload": map[string]int{"points": 100}, "quantity": 1})
		} else if p == 2 { // 10人 -> 优惠券ID 1
			r2 = append(r2, map[string]any{"tier_id": tid, "reward_type": "coupon", "reward_payload": map[string]int{"coupon_id": 1}, "quantity": 1})
		} else if p == 3 { // 100人 -> 道具卡ID 1
			r2 = append(r2, map[string]any{"tier_id": tid, "reward_type": "item_card", "reward_payload": map[string]int{"card_id": 1, "quantity": 1}, "quantity": 1})
		}
	}
	upsertRewards(t2ID, r2)
	fmt.Printf("Created Task [Daily Invite]: %d\n", t2ID)

	// ---------------------------------------------------------
	// 任务 3: 新人首单福利 (Newbie First Order) - Lifetime
	// ---------------------------------------------------------
	t3ID := createTask("新人首单福利", "完成首次订单，获得新人专属奖励", 1, 1)
	upsertTiers(t3ID, []map[string]any{
		{"metric": "first_order", "operator": "==", "threshold": 1, "window": "lifetime", "repeatable": 0, "priority": 1},
	})
	t3Tiers := listTiers(t3ID)
	var r3 []map[string]any
	for _, t := range t3Tiers {
		// 首单奖励 500 积分
		r3 = append(r3, map[string]any{"tier_id": int64(t["ID"].(float64)), "reward_type": "points", "reward_payload": map[string]int{"points": 500}, "quantity": 1})
	}
	upsertRewards(t3ID, r3)
	fmt.Printf("Created Task [Newbie First Order]: %d\n", t3ID)

	// ---------------------------------------------------------
	// 任务 4: 邀请达人 (Master Inviter) - Lifetime Cumulative
	// ---------------------------------------------------------
	t4ID := createTask("邀请达人挑战", "累计邀请好友，解锁达人成就", 1, 1)
	upsertTiers(t4ID, []map[string]any{
		{"metric": "invite_count", "operator": ">=", "threshold": 50, "window": "lifetime", "repeatable": 0, "priority": 1},
		{"metric": "invite_count", "operator": ">=", "threshold": 200, "window": "lifetime", "repeatable": 0, "priority": 2},
		{"metric": "invite_count", "operator": ">=", "threshold": 500, "window": "lifetime", "repeatable": 0, "priority": 3},
	})
	t4Tiers := listTiers(t4ID)
	var r4 []map[string]any
	for _, t := range t4Tiers {
		p := int(t["Priority"].(float64))
		tid := int64(t["ID"].(float64))
		if p == 1 { // 50人 -> 道具卡 ID 1 x2
			r4 = append(r4, map[string]any{"tier_id": tid, "reward_type": "item_card", "reward_payload": map[string]int{"card_id": 1, "quantity": 2}, "quantity": 2})
		} else if p == 2 { // 200人 -> 优惠券 ID 1 x5
			r4 = append(r4, map[string]any{"tier_id": tid, "reward_type": "coupon", "reward_payload": map[string]int{"coupon_id": 1}, "quantity": 5})
		} else if p == 3 { // 500人 -> 10000 积分
			r4 = append(r4, map[string]any{"tier_id": tid, "reward_type": "points", "reward_payload": map[string]int{"points": 10000}, "quantity": 1})
		}
	}
	upsertRewards(t4ID, r4)
	fmt.Printf("Created Task [Master Inviter]: %d\n", t4ID)

	fmt.Println("All tasks setup completed!")
}

func doRequest(method, path string, body any) map[string]any {
	var bodyReader io.Reader
	if body != nil {
		b, _ := json.Marshal(body)
		bodyReader = bytes.NewReader(b)
	}
	req, _ := http.NewRequest(method, BaseURL+path, bodyReader)
	req.Header.Set("Authorization", Token)
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	b, _ := io.ReadAll(resp.Body)
	if resp.StatusCode >= 400 {
		panic(fmt.Sprintf("Status: %d, Body: %s", resp.StatusCode, string(b)))
	}

	var res map[string]any
	json.Unmarshal(b, &res)
	return res
}

func doRequestRaw(method, path string, body any) []byte {
	var bodyReader io.Reader
	if body != nil {
		b, _ := json.Marshal(body)
		bodyReader = bytes.NewReader(b)
	}
	req, _ := http.NewRequest(method, BaseURL+path, bodyReader)
	req.Header.Set("Authorization", Token)
	if body != nil {
		req.Header.Set("Content-Type", "application/json")
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	b, _ := io.ReadAll(resp.Body)
	return b
}

func createTask(name, desc string, status, visibility int) int64 {
	res := doRequest("POST", "/api/admin/task-center/tasks", map[string]any{
		"name": name, "description": desc, "status": status, "visibility": visibility,
	})
	return int64(res["id"].(float64))
}

func upsertTiers(taskID int64, tiers []map[string]any) {
	doRequest("POST", fmt.Sprintf("/api/admin/task-center/tasks/%d/tiers", taskID), map[string]any{
		"tiers": tiers,
	})
}

func listTiers(taskID int64) []map[string]any {
	res := doRequest("GET", fmt.Sprintf("/api/admin/task-center/tasks/%d/tiers", taskID), nil)
	list := res["list"].([]interface{})
	var ret []map[string]any
	for _, v := range list {
		ret = append(ret, v.(map[string]any))
	}
	return ret
}

func upsertRewards(taskID int64, rewards []map[string]any) {
	doRequest("POST", fmt.Sprintf("/api/admin/task-center/tasks/%d/rewards", taskID), map[string]any{
		"rewards": rewards,
	})
}
