// fastocr.go — fastOcr 验证码识别 Go SDK（零依赖，单文件）
// 用法: 把此文件复制到项目中，import 后调用
package fastocr

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

type Client struct {
	ApiKey   string
	BaseURL  string
	HTTP     *http.Client
}

func New(apiKey string) *Client {
	return &Client{
		ApiKey:  apiKey,
		BaseURL: "http://shenzheng.cstext.top:8989",
		HTTP:    &http.Client{Timeout: 30 * time.Second},
	}
}

type RecognizeResult struct {
	Code       int                    `json:"code"`
	RequestID  string                 `json:"request_id"`
	Type       string                 `json:"type"`
	Result     map[string]interface{} `json:"result"`
	Cost       int                    `json:"cost"`
	LatencyMs  int                    `json:"latency_ms"`
	Balance    int                    `json:"balance"`
}

func (c *Client) Recognize(captchaType, imagePath string, piecePath ...string) (*RecognizeResult, error) {
	imgB64, err := fileToBase64(imagePath)
	if err != nil {
		return nil, err
	}
	body := map[string]string{"type": captchaType, "image": imgB64}
	if len(piecePath) > 0 && piecePath[0] != "" {
		pieceB64, err := fileToBase64(piecePath[0])
		if err != nil {
			return nil, err
		}
		body["piece"] = pieceB64
	}
	jsonBody, _ := json.Marshal(body)

	req, _ := http.NewRequest("POST", c.BaseURL+"/api/v1/captcha/recognize", bytes.NewBuffer(jsonBody))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+c.ApiKey)

	resp, err := c.HTTP.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	data, _ := io.ReadAll(resp.Body)

	var result RecognizeResult
	json.Unmarshal(data, &result)
	return &result, nil
}

func (c *Client) GetBalance() (int, error) {
	req, _ := http.NewRequest("POST", c.BaseURL+"/api/v1/user/balance", nil)
	req.Header.Set("Authorization", "Bearer "+c.ApiKey)
	resp, err := c.HTTP.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()
	var result struct {
		Data struct{ Balance int } `json:"data"`
	}
	json.NewDecoder(resp.Body).Decode(&result)
	return result.Data.Balance, nil
}

func fileToBase64(path string) (string, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return "", fmt.Errorf("读取文件失败: %v", err)
	}
	return base64.StdEncoding.EncodeToString(data), nil
}
