package handler

import (
	"net/http"
	"github.com/gin-gonic/gin"
	"github.com/google/generative-ai-go/genai"
	"google.golang.org/api/option"
	"encoding/json"
	"strings"
)

type RateHandler struct {
	geminiAPIKey string
	apiKey       string
}

type RateRequest struct {
	Content    string `json:"content" binding:"required"`
	Criteria   string `json:"criteria"`
	WritingRequirement string `json:"writing_requirement"`
	APIKey     string `json:"apikey" binding:"required"`
}

type RateResponse struct {
	Rate        int    `json:"rate"`
	Summary     string `json:"summary"`
	DetailedReview string `json:"detailed_review"`
	Success     bool   `json:"success"`
}

func NewRateHandler(geminiAPIKey, apiKey string) *RateHandler {
	return &RateHandler{
		geminiAPIKey: geminiAPIKey,
		apiKey:       apiKey,
	}
}

func (h *RateHandler) HandleRate(c *gin.Context) {
	var req RateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, RateResponse{
			Success: false,
		})
		return
	}

	// Validate API key
	if req.APIKey != h.apiKey {
		c.JSON(http.StatusUnauthorized, RateResponse{
			Success: false,
		})
		return
	}

	// Initialize Gemini client
	ctx := c.Request.Context()
	client, err := genai.NewClient(ctx, option.WithAPIKey(h.geminiAPIKey))
	if err != nil {
		c.JSON(http.StatusInternalServerError, RateResponse{
			Success: false,
		})
		return
	}
	defer client.Close()

	// Prepare criteria
	criteria := req.Criteria
	if criteria == "" {
		criteria = `你是一名语文老师。你正在给学生的作文打分。根据以下中考作文评分标准，给作文打分。
## 评分总分值：100分。
###  88-100分 符合题意；写作目的和对象明确；思考充分，立意深刻，感情真挚；选材精当，内容充实；中心突出，条理清晰；表达准确，语言流畅。
###  75-87分 符合题意；写作目的和对象较明确；思考较充分，立意清楚，感情真实；选材合理，内容具体；中心明确，有一定条理；表达较准确，语言通畅。
###  60-74分 符合题意；写作目的和对象较模糊；有一定思考，感情真实；有一定内容；结构基本完整；语言尚通畅。
###  60分以下 不符合题意；缺乏写作目的和对象；基本没有思考，感情虚假；内容空洞；结构混乱；不成篇。`
	}
	writing_requirement := req.WritingRequirement
	if writing_requirement == "" {
		writing_requirement = "写一篇不少于600字的作文，体裁不限。"
	}
	
	// 规定输出格式是json，包含rate, summary, detailed_review，放入prompt的最后
	format := `请按照以下JSON格式输出：
{
	"rate": 分数, // 最多100分制的分数，int类型
	"summary": "总体评价", // 100字以内的总体评价，string类型
	"detailed_review": "详细点评" // 300字以内的详细点评，包含优点和建议，string类型
}`
	// Prepare prompt
	prompt := "作文要求：\n" + writing_requirement + "\n\n" + "评分标准：\n" + criteria + format + "\n\n" + "\n\n作文内容：\n" + req.Content 

	// Generate content
	model := client.GenerativeModel("gemini-2.0-flash-exp")
	resp, err := model.GenerateContent(ctx, genai.Text(prompt))
	if err != nil {
		c.JSON(http.StatusInternalServerError, RateResponse{
			Success: false,
		})
		return
	}

	if len(resp.Candidates) > 0 && len(resp.Candidates[0].Content.Parts) > 0 {
		if textPart, ok := resp.Candidates[0].Content.Parts[0].(genai.Text); ok {
			// Parse the response to extract rate, summary, and detailed review
			result := parseRateResponse(string(textPart))
			
			c.JSON(http.StatusOK, RateResponse{
				Rate:          result.Rate,
				Summary:      result.Summary,
				DetailedReview: result.Detailed,
				Success:      true,
			})
			return
		}
	}

	c.JSON(http.StatusInternalServerError, RateResponse{
		Success: false,
	})
}

type rateResult struct {
	Rate     int    `json:"rate"`
	Summary  string `json:"summary"`
	Detailed string `json:"detailed_review"`
}

func parseRateResponse(response string) rateResult {
	var result rateResult
	//去除所有\n
	response = strings.ReplaceAll(response, "\n", "")
	//去除所有\t
	response = strings.ReplaceAll(response, "\t", "")
	// 去除response中的```json前缀和```后缀
	response = strings.TrimSpace(response)
	response = strings.TrimPrefix(response, "```json")
	response = strings.TrimSuffix(response, "```")
	

	// 检查response是否是json格式
	if !strings.HasPrefix(response, "{") {
		return rateResult{
			Rate:     0,
			Summary:  "解析失败",
			Detailed: "没有左括号",
		}
	}
	if !strings.HasSuffix(response, "}") {
		return rateResult{
			Rate:     0,
			Summary:  "解析失败",
			Detailed: "没有右括号",
		}
	}

	// 解析json
	err := json.Unmarshal([]byte(response), &result)
	if err != nil {
		return rateResult{
			Rate:     0,
			Summary:  "解析失败",
			Detailed: "反序列化失败",
		}
	}

	// 合并所有验证条件
	if result.Rate <= 0 || result.Rate > 100 || 
	   result.Summary == "" || result.Detailed == "" {
		return rateResult{
			Rate:     0,
			Summary:  "解析失败",
			Detailed: "字段验证条件不满足",
		}
	}

	return result
}