package app

import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"mime/multipart"

	"git.echol.cn/loser/st/server/global"
	"git.echol.cn/loser/st/server/model/app"
	"git.echol.cn/loser/st/server/model/app/request"
	"git.echol.cn/loser/st/server/model/app/response"
	"git.echol.cn/loser/st/server/utils"
	"gorm.io/datatypes"
	"gorm.io/gorm"
)

type CharacterService struct{}

// CreateCharacter 创建角色卡
func (s *CharacterService) CreateCharacter(userID uint, req *request.CreateCharacterRequest) (*response.CharacterResponse, error) {
	// 序列化 JSON 字段
	tagsJSON, _ := json.Marshal(req.Tags)
	alternateGreetingsJSON, _ := json.Marshal(req.AlternateGreetings)
	characterBookJSON, _ := json.Marshal(req.CharacterBook)
	extensionsJSON, _ := json.Marshal(req.Extensions)

	character := app.AICharacter{
		UserID:                  userID,
		Name:                    req.Name,
		Avatar:                  req.Avatar,
		Creator:                 req.Creator,
		Version:                 req.Version,
		Description:             req.Description,
		Personality:             req.Personality,
		Scenario:                req.Scenario,
		FirstMes:                req.FirstMes,
		MesExample:              req.MesExample,
		CreatorNotes:            req.CreatorNotes,
		SystemPrompt:            req.SystemPrompt,
		PostHistoryInstructions: req.PostHistoryInstructions,
		Tags:                    datatypes.JSON(tagsJSON),
		AlternateGreetings:      datatypes.JSON(alternateGreetingsJSON),
		CharacterBook:           datatypes.JSON(characterBookJSON),
		Extensions:              datatypes.JSON(extensionsJSON),
		IsPublic:                req.IsPublic,
		Spec:                    "chara_card_v2",
		SpecVersion:             "2.0",
	}

	err := global.GVA_DB.Create(&character).Error
	if err != nil {
		return nil, err
	}

	resp := response.ToCharacterResponse(&character)
	return &resp, nil
}

// GetCharacterList 获取角色卡列表
func (s *CharacterService) GetCharacterList(userID uint, req *request.GetCharacterListRequest) (*response.CharacterListResponse, error) {
	var characters []app.AICharacter
	var total int64

	db := global.GVA_DB.Model(&app.AICharacter{})

	// 筛选条件
	if req.IsPublic != nil {
		if *req.IsPublic {
			db = db.Where("is_public = ?", true)
		} else {
			db = db.Where("user_id = ?", userID)
		}
	} else {
		db = db.Where("user_id = ? OR is_public = ?", userID, true)
	}

	// 关键词搜索
	if req.Keyword != "" {
		db = db.Where("name LIKE ? OR description LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	// 标签筛选
	if req.Tag != "" {
		db = db.Where("tags @> ?", datatypes.JSON(`["`+req.Tag+`"]`))
	}

	// 统计总数
	err := db.Count(&total).Error
	if err != nil {
		return nil, err
	}

	// 分页查询
	offset := (req.Page - 1) * req.PageSize
	err = db.Order("created_at DESC").Offset(offset).Limit(req.PageSize).Find(&characters).Error
	if err != nil {
		return nil, err
	}

	// 转换响应
	list := make([]response.CharacterResponse, len(characters))
	for i, char := range characters {
		list[i] = response.ToCharacterResponse(&char)
	}

	return &response.CharacterListResponse{
		List:     list,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}, nil
}

// GetCharacterByID 获取角色卡详情
func (s *CharacterService) GetCharacterByID(userID, characterID uint) (*response.CharacterResponse, error) {
	var character app.AICharacter

	err := global.GVA_DB.Where("id = ? AND (user_id = ? OR is_public = ?)", characterID, userID, true).
		First(&character).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("角色卡不存在或无权访问")
		}
		return nil, err
	}

	resp := response.ToCharacterResponse(&character)
	return &resp, nil
}

// UpdateCharacter 更新角色卡
func (s *CharacterService) UpdateCharacter(userID, characterID uint, req *request.UpdateCharacterRequest) error {
	var character app.AICharacter

	// 检查权限
	err := global.GVA_DB.Where("id = ? AND user_id = ?", characterID, userID).First(&character).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("角色卡不存在或无权修改")
		}
		return err
	}

	// 更新字段
	updates := map[string]interface{}{}

	if req.Name != "" {
		updates["name"] = req.Name
	}
	if req.Avatar != "" {
		updates["avatar"] = req.Avatar
	}
	if req.Creator != "" {
		updates["creator"] = req.Creator
	}
	if req.Version != "" {
		updates["version"] = req.Version
	}
	if req.Description != "" {
		updates["description"] = req.Description
	}
	if req.Personality != "" {
		updates["personality"] = req.Personality
	}
	if req.Scenario != "" {
		updates["scenario"] = req.Scenario
	}
	if req.FirstMes != "" {
		updates["first_mes"] = req.FirstMes
	}
	if req.MesExample != "" {
		updates["mes_example"] = req.MesExample
	}
	if req.CreatorNotes != "" {
		updates["creator_notes"] = req.CreatorNotes
	}
	if req.SystemPrompt != "" {
		updates["system_prompt"] = req.SystemPrompt
	}
	if req.PostHistoryInstructions != "" {
		updates["post_history_instructions"] = req.PostHistoryInstructions
	}

	if req.Tags != nil {
		tagsJSON, _ := json.Marshal(req.Tags)
		updates["tags"] = datatypes.JSON(tagsJSON)
	}
	if req.AlternateGreetings != nil {
		alternateGreetingsJSON, _ := json.Marshal(req.AlternateGreetings)
		updates["alternate_greetings"] = datatypes.JSON(alternateGreetingsJSON)
	}
	if req.CharacterBook != nil {
		characterBookJSON, _ := json.Marshal(req.CharacterBook)
		updates["character_book"] = datatypes.JSON(characterBookJSON)
	}
	if req.Extensions != nil {
		extensionsJSON, _ := json.Marshal(req.Extensions)
		updates["extensions"] = datatypes.JSON(extensionsJSON)
	}

	updates["is_public"] = req.IsPublic

	return global.GVA_DB.Model(&character).Updates(updates).Error
}

// DeleteCharacter 删除角色卡
func (s *CharacterService) DeleteCharacter(userID, characterID uint) error {
	result := global.GVA_DB.Where("id = ? AND user_id = ?", characterID, userID).Delete(&app.AICharacter{})
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("角色卡不存在或无权删除")
	}
	return nil
}

// ImportCharacterFromPNG 从 PNG 文件导入角色卡
func (s *CharacterService) ImportCharacterFromPNG(userID uint, file *multipart.FileHeader) (*response.CharacterResponse, error) {
	// 读取文件内容
	src, err := file.Open()
	if err != nil {
		return nil, errors.New("打开文件失败")
	}
	defer src.Close()

	// 读取文件数据
	fileData := make([]byte, file.Size)
	_, err = src.Read(fileData)
	if err != nil {
		return nil, errors.New("读取文件失败")
	}

	// 提取角色卡数据
	card, err := utils.ExtractCharacterFromPNG(fileData)
	if err != nil {
		return nil, err
	}

	// 上传 PNG 图片到 OSS（替代 Base64）
	var uploadService UploadService
	avatarURL, err := uploadService.UploadImage(file)
	if err != nil {
		// 如果上传失败，回退到 Base64（向后兼容）
		avatarURL = "data:image/png;base64," + base64.StdEncoding.EncodeToString(fileData)
	}

	// 转换为创建请求
	req := &request.CreateCharacterRequest{
		Name:                    card.Data.Name,
		Avatar:                  avatarURL,
		Creator:                 card.Data.Creator,
		Version:                 card.Data.CharacterVersion,
		Description:             card.Data.Description,
		Personality:             card.Data.Personality,
		Scenario:                card.Data.Scenario,
		FirstMes:                card.Data.FirstMes,
		MesExample:              card.Data.MesExample,
		CreatorNotes:            card.Data.CreatorNotes,
		SystemPrompt:            card.Data.SystemPrompt,
		PostHistoryInstructions: card.Data.PostHistoryInstructions,
		Tags:                    card.Data.Tags,
		AlternateGreetings:      card.Data.AlternateGreetings,
		CharacterBook:           card.Data.CharacterBook,
		Extensions:              card.Data.Extensions,
		IsPublic:                false,
	}

	// 创建角色卡
	resp, err := s.CreateCharacter(userID, req)
	if err != nil {
		return nil, err
	}

	// 处理扩展数据中的正则脚本
	if card.Data.Extensions != nil {
		s.processRegexScriptsFromExtensions(userID, resp.ID, card.Data.Extensions)
	}

	return resp, nil
}

// ImportCharacterFromJSON 从 JSON 文件导入角色卡
func (s *CharacterService) ImportCharacterFromJSON(userID uint, file *multipart.FileHeader) (*response.CharacterResponse, error) {
	// 读取文件内容
	src, err := file.Open()
	if err != nil {
		return nil, errors.New("打开文件失败")
	}
	defer src.Close()

	// 读取文件数据
	fileData := make([]byte, file.Size)
	_, err = src.Read(fileData)
	if err != nil {
		return nil, errors.New("读取文件失败")
	}

	// 解析 JSON
	card, err := utils.ParseCharacterCardJSON(fileData)
	if err != nil {
		return nil, err
	}

	// 转换为创建请求
	req := &request.CreateCharacterRequest{
		Name:                    card.Data.Name,
		Creator:                 card.Data.Creator,
		Version:                 card.Data.CharacterVersion,
		Description:             card.Data.Description,
		Personality:             card.Data.Personality,
		Scenario:                card.Data.Scenario,
		FirstMes:                card.Data.FirstMes,
		MesExample:              card.Data.MesExample,
		CreatorNotes:            card.Data.CreatorNotes,
		SystemPrompt:            card.Data.SystemPrompt,
		PostHistoryInstructions: card.Data.PostHistoryInstructions,
		Tags:                    card.Data.Tags,
		AlternateGreetings:      card.Data.AlternateGreetings,
		CharacterBook:           card.Data.CharacterBook,
		Extensions:              card.Data.Extensions,
		IsPublic:                false,
	}

	// 创建角色卡
	resp, err := s.CreateCharacter(userID, req)
	if err != nil {
		return nil, err
	}

	// 处理扩展数据中的正则脚本
	if card.Data.Extensions != nil {
		s.processRegexScriptsFromExtensions(userID, resp.ID, card.Data.Extensions)
	}

	return resp, nil
}

// ExportCharacterToJSON 导出角色卡为 JSON
func (s *CharacterService) ExportCharacterToJSON(userID, characterID uint) (*utils.CharacterCardV2, error) {
	var character app.AICharacter

	err := global.GVA_DB.Where("id = ? AND (user_id = ? OR is_public = ?)", characterID, userID, true).
		First(&character).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("角色卡不存在或无权访问")
		}
		return nil, err
	}

	// 解析 JSON 字段
	var tags []string
	var alternateGreetings []string
	var characterBook map[string]interface{}
	var extensions map[string]interface{}

	json.Unmarshal(character.Tags, &tags)
	json.Unmarshal(character.AlternateGreetings, &alternateGreetings)
	json.Unmarshal(character.CharacterBook, &characterBook)
	json.Unmarshal(character.Extensions, &extensions)

	// 查询角色关联的正则脚本并添加到 extensions
	var regexScripts []app.RegexScript
	global.GVA_DB.Where("owner_char_id = ? AND scope = 1", characterID).Find(&regexScripts)
	if len(regexScripts) > 0 {
		if extensions == nil {
			extensions = make(map[string]interface{})
		}
		extensions["regex_scripts"] = regexScripts
	}

	// 构建 V2 格式
	card := &utils.CharacterCardV2{
		Spec:        character.Spec,
		SpecVersion: character.SpecVersion,
		Data: utils.CharacterCardV2Data{
			Name:                    character.Name,
			Description:             character.Description,
			Personality:             character.Personality,
			Scenario:                character.Scenario,
			FirstMes:                character.FirstMes,
			MesExample:              character.MesExample,
			CreatorNotes:            character.CreatorNotes,
			SystemPrompt:            character.SystemPrompt,
			PostHistoryInstructions: character.PostHistoryInstructions,
			Tags:                    tags,
			Creator:                 character.Creator,
			CharacterVersion:        character.Version,
			AlternateGreetings:      alternateGreetings,
			CharacterBook:           characterBook,
			Extensions:              extensions,
		},
	}

	return card, nil
}

// processRegexScriptsFromExtensions 从扩展数据中提取并创建正则脚本
func (s *CharacterService) processRegexScriptsFromExtensions(userID, characterID uint, extensions map[string]interface{}) {
	// 检查是否包含正则脚本
	regexScriptsData, ok := extensions["regex_scripts"]
	if !ok {
		return
	}

	// 转换为 JSON 以便解析
	scriptsJSON, err := json.Marshal(regexScriptsData)
	if err != nil {
		global.GVA_LOG.Error("序列化正则脚本失败: " + err.Error())
		return
	}

	// 解析正则脚本数组
	var scripts []map[string]interface{}
	if err := json.Unmarshal(scriptsJSON, &scripts); err != nil {
		global.GVA_LOG.Error("解析正则脚本失败: " + err.Error())
		return
	}

	// 创建正则脚本记录
	for _, scriptData := range scripts {
		script := app.RegexScript{
			UserID:      userID,
			Scope:       1, // 角色作用域
			OwnerCharID: &characterID,
		}

		// 提取字段 - 兼容 SillyTavern 的字段名
		// 脚本名称：优先使用 scriptName，其次 name
		if scriptName, ok := scriptData["scriptName"].(string); ok {
			script.Name = scriptName
		} else if name, ok := scriptData["name"].(string); ok {
			script.Name = name
		}

		// 查找正则表达式
		if findRegex, ok := scriptData["findRegex"].(string); ok {
			script.FindRegex = findRegex
		}

		// 替换字符串：优先使用 replaceString，其次 replaceWith
		if replaceString, ok := scriptData["replaceString"].(string); ok {
			script.ReplaceWith = replaceString
		} else if replaceWith, ok := scriptData["replaceWith"].(string); ok {
			script.ReplaceWith = replaceWith
		}
		if placement, ok := scriptData["placement"].(float64); ok {
			script.Placement = int(placement)
		}
		if disabled, ok := scriptData["disabled"].(bool); ok {
			script.Disabled = disabled
		}
		if markdownOnly, ok := scriptData["markdownOnly"].(bool); ok {
			script.MarkdownOnly = markdownOnly
		}
		if runOnEdit, ok := scriptData["runOnEdit"].(bool); ok {
			script.RunOnEdit = runOnEdit
		}
		if promptOnly, ok := scriptData["promptOnly"].(bool); ok {
			script.PromptOnly = promptOnly
		}
		if substituteRegex, ok := scriptData["substituteRegex"].(bool); ok {
			script.SubstituteRegex = substituteRegex
		}
		if order, ok := scriptData["order"].(float64); ok {
			script.Order = int(order)
		}

		// 处理可选的整数字段
		if minDepth, ok := scriptData["minDepth"].(float64); ok {
			depth := int(minDepth)
			script.MinDepth = &depth
		}
		if maxDepth, ok := scriptData["maxDepth"].(float64); ok {
			depth := int(maxDepth)
			script.MaxDepth = &depth
		}

		// 处理 trimStrings 数组
		if trimStrings, ok := scriptData["trimStrings"].([]interface{}); ok {
			trimStringsJSON, _ := json.Marshal(trimStrings)
			script.TrimStrings = datatypes.JSON(trimStringsJSON)
		}

		// 处理扩展字段
		if scriptExtensions, ok := scriptData["extensions"].(map[string]interface{}); ok {
			extensionsJSON, _ := json.Marshal(scriptExtensions)
			script.Extensions = datatypes.JSON(extensionsJSON)
		}

		// 创建记录
		if err := global.GVA_DB.Create(&script).Error; err != nil {
			global.GVA_LOG.Error("创建正则脚本失败: " + err.Error())
		}
	}
}
