package parser

import "encoding/json"

type StreamParser func(line string)

type Parser struct {
	Parse StreamParser
	Flush func()
}

// CreateStreamParser 建立串流解析器（向後相容，不傳遞 thinking）
func CreateStreamParser(onText func(string), onDone func()) Parser {
	return CreateStreamParserWithThinking(onText, nil, onDone)
}

// CreateStreamParserWithThinking 建立串流解析器，支援思考過程輸出。
// onThinking 可為 nil，表示忽略思考過程。
func CreateStreamParserWithThinking(onText func(string), onThinking func(string), onDone func()) Parser {
	accumulatedText := ""
	accumulatedThinking := ""
	done := false

	parse := func(line string) {
		if done {
			return
		}

		var obj struct {
			Type    string `json:"type"`
			Subtype string `json:"subtype"`
			Message *struct {
				Content []struct {
					Type     string `json:"type"`
					Text     string `json:"text"`
					Thinking string `json:"thinking"`
				} `json:"content"`
			} `json:"message"`
		}

		if err := json.Unmarshal([]byte(line), &obj); err != nil {
			return
		}

		if obj.Type == "assistant" && obj.Message != nil {
			fullText := ""
			fullThinking := ""
			for _, p := range obj.Message.Content {
				switch p.Type {
				case "text":
					if p.Text != "" {
						fullText += p.Text
					}
				case "thinking":
					if p.Thinking != "" {
						fullThinking += p.Thinking
					}
				}
			}

			// 處理思考過程 delta
			if onThinking != nil && fullThinking != "" {
				if fullThinking == accumulatedThinking {
					// 重複的完整思考文字，跳過
				} else if len(fullThinking) > len(accumulatedThinking) && fullThinking[:len(accumulatedThinking)] == accumulatedThinking {
					delta := fullThinking[len(accumulatedThinking):]
					onThinking(delta)
					accumulatedThinking = fullThinking
				} else {
					onThinking(fullThinking)
					accumulatedThinking += fullThinking
				}
			}

			// 處理一般文字 delta
			if fullText == "" {
				return
			}
			// 若此訊息文字等於已累積內容（重複的完整文字），跳過
			if fullText == accumulatedText {
				return
			}
			// 若此訊息是已累積內容的延伸，只輸出新的 delta
			if len(fullText) > len(accumulatedText) && fullText[:len(accumulatedText)] == accumulatedText {
				delta := fullText[len(accumulatedText):]
				onText(delta)
				accumulatedText = fullText
			} else {
				// 獨立的 token fragment（一般情況），直接輸出
				onText(fullText)
				accumulatedText += fullText
			}
		}

		if obj.Type == "result" && obj.Subtype == "success" {
			done = true
			onDone()
		}
	}

	flush := func() {
		if !done {
			done = true
			onDone()
		}
	}

	return Parser{Parse: parse, Flush: flush}
}
