//go:build ignore

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"time"
)

func main() {
	base := "http://127.0.0.1:8888"

	fmt.Println("== token ==")
	tokBody, _ := json.Marshal(map[string]any{
		"tenant_id": 1,
		"user_id":   1,
		"secret":    "dev-only-change-me",
	})
	code, raw := do(http.MethodPost, base+"/api/v1/auth/token", tokBody, "")
	fmt.Printf("status=%d\n%s\n", code, raw)
	var tok struct {
		AccessToken string `json:"access_token"`
	}
	must(json.Unmarshal(raw, &tok))
	if tok.AccessToken == "" {
		panic("empty access_token")
	}
	bearer := tok.AccessToken

	// 若已发布则跳过 publish，验证元数据落库后重启仍可 CRUD
	fmt.Println("== blueprint (check existing) ==")
	bpCode, bpRaw := do(http.MethodGet, base+"/api/v1/apps/inventory_ledger/blueprint", nil, bearer)
	fmt.Printf("status=%d\n", bpCode)

	if bpCode != 200 {
		bpPath := filepath.Join("..", "blueprint", "examples", "inventory-ledger.blueprint.json")
		bp, err := os.ReadFile(bpPath)
		must(err)
		pubBody, _ := json.Marshal(map[string]json.RawMessage{"blueprint": bp})
		fmt.Println("== publish ==")
		printDo(http.MethodPost, base+"/api/v1/apps/inventory_ledger/publish", pubBody, bearer)
	} else {
		fmt.Println("skip publish: app already in meta store")
		fmt.Printf("%s\n", truncate(bpRaw, 200))
	}

	sku := fmt.Sprintf("A-%d", time.Now().Unix()%100000)
	row, _ := json.Marshal(map[string]any{
		"sku": sku, "product_name": "无线鼠标", "warehouse": "华东仓",
		"qty": 120, "unit_price": 59.9, "status": "在售",
	})
	fmt.Println("== create ==")
	printDo(http.MethodPost, base+"/api/v1/apps/inventory_ledger/inventory_items", row, bearer)

	q := url.Values{}
	q.Set("filter.warehouse", "华东仓")
	q.Set("sort", "-qty")
	fmt.Println("== list ==")
	printDo(http.MethodGet, base+"/api/v1/apps/inventory_ledger/inventory_items?"+q.Encode(), nil, bearer)
}

func truncate(b []byte, n int) string {
	if len(b) <= n {
		return string(b)
	}
	return string(b[:n]) + "..."
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

func printDo(method, rawURL string, body []byte, bearer string) {
	code, raw := do(method, rawURL, body, bearer)
	fmt.Printf("status=%d\n%s\n", code, raw)
}

func do(method, rawURL string, body []byte, bearer string) (int, []byte) {
	var r io.Reader
	if body != nil {
		r = bytes.NewReader(body)
	}
	req, err := http.NewRequest(method, rawURL, r)
	must(err)
	if body != nil {
		req.Header.Set("Content-Type", "application/json")
	}
	if bearer != "" {
		req.Header.Set("Authorization", "Bearer "+bearer)
	}
	resp, err := http.DefaultClient.Do(req)
	must(err)
	defer resp.Body.Close()
	b, _ := io.ReadAll(resp.Body)
	return resp.StatusCode, b
}
