package message

import (
	"agent/src/llm"
	"encoding/json"
	"fmt"
)

type ReponseAuthentication struct {
	Success bool    `json:"success"`
	Error   string  `json:"error"`
}

var ReponseAuthenticationFail = &ReponseAuthentication{
	Success: false,
	Error: "invalid apikey",
}

type ReponseError struct {
	Error string  `json:"error"`
}

type ReuqestCmd struct {
	Cmd       string  `json:"cmd"`
	RequestId uint64  `json:"request_id,omitempty"`
}

func ParseCmd(msg []byte) (*ReuqestCmd, error) {
	var cmd ReuqestCmd
	err := json.Unmarshal(msg, &cmd)
	if err != nil { 
		return nil, err
	}
	return &cmd, nil
}



type RequestExec struct {
	Cmd string   `json:"cmd"`
	RequestId    uint64  `json:"request_id"`
	Language     string `json:"language,omitempty"`
	Model        string  `json:"model"`
	Stream       bool    `json:"stream,omitempty"`
}

func (m *RequestExec) Check() error {
	if m.Language == "" {
		m.Language = "en"
	}
	if m.Language != "en" && m.Language != "zh" {
		return fmt.Errorf("unkown language %s", m.Language)
	}
	if !llm.ContainLLM(m.Model) {
		return fmt.Errorf("unkown model %s", m.Model)
	}
	return nil
}


type ResponseExecSuccess struct {
	RequestId     uint64  `json:"request_id"`
	Msg           string  `json:"msg"`
	Stream_SeqId  *uint64 `json:"stream_seq_id,omitempty"`
	Stream_Finish bool    `json:"stream_finish,omitempty"`
}

type ResponseExecFail struct {
	RequestId  uint64  `json:"request_id,omitempty"`
	Error      string  `json:"error"`
}



func Parse[T any](msg []byte) (*T, error) {
	var req T
	if err := json.Unmarshal(msg, &req); err != nil {
		return nil, err
	}
	return &req, nil
}

type ResponseListModel struct {
	RequestId  uint64    `json:"request_id"`
	Models     []string  `json:"models"`
}


type RequestExecExplain struct {
	RequestExec
	SelectedText TextContext  `json:"selected_text"`
	VisibleText  TextContext  `json:"visible_text"`
}

type TextContext struct {
	FilePath string    `json:"filepath"`
	Range    TextRange `json:"range"`
	Text     string    `json:"text"`
}

type TextRange struct {
	Start TextPosition `json:"start"`
	End   TextPosition `json:"end"`
}

type TextPosition struct {
	Line      int `json:"line"`
	Character int `json:"character"`
}

type RequestExecChat struct {
	RequestExec
	Msg string  `json:"msg"`
}


type RequestExecDocstring struct {
	RequestExec
	SelectedText TextContext  `json:"selected_text"`
}


type RequestExecFix struct {
	RequestExec
	SelectedText TextContext  `json:"selected_text"`
}
