package crontask

import (
	"encoding/json"
	"fmt"
	"github.com/google/uuid"
	"github.com/zeromicro/go-zero/core/logx"
	"strconv"
	"strings"
	"time"
	"wechat-api/ent/contact"
	"wechat-api/ent/contactfield"
	"wechat-api/ent/contactfieldtemplate"
	"wechat-api/ent/custom_types"
	"wechat-api/ent/predicate"
	"wechat-api/ent/usagedetail"
	"wechat-api/internal/types"
	"wechat-api/internal/utils/compapi"
)

type ResponseItem struct {
	DataIndex string   `json:"dataIndex"`
	Value     []string `json:"value"`
}

type FieldPropsOptions struct {
	Label string `json:"label"`
	Value string `json:"value"`
}

type FieldProps struct {
	Options []FieldPropsOptions `json:"options"`
}

type FormData struct {
	Title      string     `json:"title"`
	DataIndex  string     `json:"dataIndex"`
	ValueType  string     `json:"valueType"`
	FieldProps FieldProps `json:"fieldProps"`
}

func (l *CronTask) analyze() {
	usageDetails := make(map[string]map[string]string)
	contactFieldTemplates := make(map[string][]custom_types.ContactFieldTemplate)
	template_type_text := "text"
	template_type_radio := "radio"
	//template_type_date := "date"
	template_sex_id := "sex"
	template_sex_label := "性别"
	template_sex_options_man_label := "男"
	template_sex_options_man_value := "男"
	template_sex_options_woman_label := "女"
	template_sex_options_woman_value := "男"

	template_phone_id := "phone"
	template_phone_label := "手机号"

	//template_name_id := "name"
	//template_name_label := "姓名"
	//
	//template_age_id := "age"
	//template_age_label := "年龄（以字符串形式返回阿拉伯数字）"
	//
	//template_area_id := "area"
	//template_area_label := "地区"
	//
	//template_birthday_id := "birthday"
	//template_birthday_label := "出生日期"
	//
	//template_birtharea_id := "birtharea"
	//template_birtharea_label := "出生地"
	//
	//template_idcard_no_id := "idcard_no"
	//template_idcard_no_label := "身份证号"
	//
	//template_title_id := "title"
	//template_title_label := "称呼"
	contactBasicFieldTemplates := []custom_types.ContactFieldTemplate{
		{
			Label: &template_sex_label,
			Id:    &template_sex_id,
			Type:  &template_type_radio,
			Options: []custom_types.ContactFieldTemplateOptions{
				{
					Label: &template_sex_options_man_label,
					Value: &template_sex_options_man_value,
				}, {
					Label: &template_sex_options_woman_label,
					Value: &template_sex_options_woman_value,
				},
			},
		},
		{
			Label: &template_phone_label,
			Id:    &template_phone_id,
			Type:  &template_type_text,
		},
		//{
		//	Label: &template_name_label,
		//	Id:    &template_name_id,
		//	Type:  &template_type_text,
		//}, {
		//	Label: &template_age_label,
		//	Id:    &template_age_id,
		//	Type:  &template_type_text,
		//}, {
		//	Label: &template_area_label,
		//	Id:    &template_area_id,
		//	Type:  &template_type_text,
		//}, {
		//	Label: &template_birthday_label,
		//	Id:    &template_birthday_id,
		//	Type:  &template_type_date,
		//}, {
		//	Label: &template_birtharea_label,
		//	Id:    &template_birtharea_id,
		//	Type:  &template_type_text,
		//}, {
		//	Label: &template_idcard_no_label,
		//	Id:    &template_idcard_no_id,
		//	Type:  &template_type_text,
		//}, {
		//	Label: &template_title_label,
		//	Id:    &template_title_id,
		//	Type:  &template_type_text,
		//},
	}

	var predicates []predicate.UsageDetail
	predicates = append(predicates, usagedetail.TypeIn(1, 3, 4, 6))
	predicates = append(predicates, usagedetail.AppIn(1, 3, 4, 5))
	//yesterdayStart := time.Now().AddDate(0, 0, -1).Truncate(24 * time.Hour)
	//yesterdayEnd := yesterdayStart.Add(24 * time.Hour)
	loc, _ := time.LoadLocation("Asia/Shanghai")
	now := time.Now().In(loc)
	yesterdayEnd := now.Truncate(24 * time.Hour)
	yesterdayStart := yesterdayEnd.AddDate(0, 0, -2)
	predicates = append(predicates, usagedetail.CreatedAtGTE(yesterdayStart))
	predicates = append(predicates, usagedetail.CreatedAtLT(yesterdayEnd))

	//todayStart := time.Now().AddDate(0, 0, 0).Truncate(24 * time.Hour)
	//todayEnd := todayStart.Add(24 * time.Hour)
	//predicates = append(predicates, usagedetail.CreatedAtGTE(todayStart))
	//predicates = append(predicates, usagedetail.CreatedAtLT(todayEnd))

	data, err := l.svcCtx.DB.UsageDetail.Query().Where(predicates...).All(l.ctx)
	logx.Info("usageDetails: ", data)
	if err != nil {
		return
	}

	wxs, err := l.svcCtx.DB.Wx.Query().All(l.ctx)
	if err != nil {
		return
	}

	for _, wx := range wxs {
		c, _ := l.svcCtx.DB.ContactFieldTemplate.Query().Where(contactfieldtemplate.OrganizationID(wx.OrganizationID)).First(l.ctx)
		if c != nil {
			contactFieldTemplates[wx.Wxid] = c.Template
		} else {
			contactFieldTemplates[wx.Wxid] = nil
		}
	}

	for _, u := range data {
		if contactFieldTemplates[u.BotID] == nil {
			continue
		}
		if _, ok := usageDetails[u.BotID]; !ok {
			usageDetails[u.BotID] = make(map[string]string)
		}
		usageDetails[u.BotID][u.ReceiverID] += fmt.Sprintf("用户：%s\n机器人：%s\n", u.Request, u.Response)
	}
	logx.Info("usageDetails: ", usageDetails)
	for botID, template := range contactFieldTemplates {
		if template == nil {
			template = contactBasicFieldTemplates
		} else {
			template = append(template, contactBasicFieldTemplates...)
		}
		for receiverID, messages := range usageDetails[botID] {
			result, _ := l.openaiRequest(messages, template)
			logx.Info("result: ", result)
			if result == nil {
				continue
			}
			_ = l.UpdateContactFields(botID, receiverID, result)
		}
	}

}

func (l *CronTask) openaiRequest(messages string, template []custom_types.ContactFieldTemplate) ([]ResponseItem, error) {
	formData := ConvertFormData(template)
	jsonBytes, err := json.Marshal(formData)
	if err != nil {
		return nil, err
	}
	jsonStr := string(jsonBytes)
	logx.Info("contactFieldTemplates: ", jsonStr)
	req := &types.CompApiReq{
		types.CompCtlReq{
			"form",
			"",
			false,
			"",
		},
		types.StdCompApiReq{
			"gpt-4o",
			[]types.StdCompMessage{},
			false,
			nil,
		},
		types.FastGptSpecReq{
			"",
			"",
			"",
			false,
			map[string]string{
				"form_data":    jsonStr,
				"chat_history": messages,
				"external_id":  uuid.New().String(),
			},
		},
	}
	resp, err := compapi.NewClient(l.ctx, compapi.WithApiBase("http://new-api.gkscrm.com/v1/"),
		compapi.WithApiKey("sk-wwttAtdLcTfeF7F2Eb9d3592Bd4c487f8e8fA544D6C4BbA9")).
		Chat(req)
	logx.Info("resp: ", resp)
	if err == nil && resp != nil && len(resp.Choices) > 0 {
		logx.Info("resp.Choices: ", resp.Choices[0].Message.Content)
		// 尝试第一层解析成 string

		items, err := parseContent(resp.Choices[0].Message.Content)
		if err != nil {
			return nil, err
		}
		return items, nil
	} else if resp != nil && len(resp.Choices) == 0 {
		return nil, err
	}
	//url := "https://toolsapi-debug.gkscrm.com/call_center/form/extract"
	//bodyData := map[string]interface{}{
	//	"form_data":    ConvertFormData(template),
	//	"chat_history": messages,
	//	"external_id":  uuid.New().String(),
	//}
	//logx.Info("bodyData: %+v", bodyData)
	//bodyBytes, err := json.Marshal(bodyData)
	//if err != nil {
	//	return nil, err
	//}
	//
	//req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes))
	//if err != nil {
	//	return nil, err
	//}
	//req.Header.Set("Content-Type", "application/json")
	//req.Header.Set("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIn0.ZS9jnsLPCnmc8L_lu4yaQFp34vwWF1mHlHSBYrY5JVs")
	//
	//client := &http.Client{}
	//resp, err := client.Do(req)
	//if err != nil || resp == nil || resp.Body == nil {
	//	logx.Error("read body error: ", err)
	//	return nil, err
	//}
	//
	//logx.Info("err: ", err)
	//if err != nil {
	//	return nil, err
	//}
	//defer resp.Body.Close()
	//
	//if resp.StatusCode != http.StatusOK {
	//	return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
	//}
	//
	////var result []ResponseItem
	//var fullResp struct {
	//	Data []ResponseItem `json:"data"`
	//}
	//err = json.NewDecoder(resp.Body).Decode(&fullResp)
	//if err != nil {
	//	return nil, err
	//}
	//
	//return fullResp.Data, nil
	return nil, err
}

func (l *CronTask) UpdateContactFields(botID string, receiverID string, fields []ResponseItem) error {
	basic_ids := []string{"sex", "phone", "name", "age", "area", "birthday", "birtharea", "idcard_no", "title"}
	c, _ := l.svcCtx.DB.Contact.Query().Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).First(l.ctx)
	if c == nil {
		return fmt.Errorf("Contact not find")
	}
	for _, field := range fields {
		if contains(basic_ids, field.DataIndex) {
			if len(field.Value) == 0 {
				continue
			}
			value := 0
			if field.DataIndex == "sex" && c.Sex == 0 {
				if field.Value[0] == "男" {
					value = 1
				} else if field.Value[0] == "女" {
					value = 2
				}
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetSex(value).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "phone" && c.Phone == "" {
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetPhone(field.Value[0]).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "name" && c.Cname == "" {
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetCname(field.Value[0]).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "age" && c.Cage == 0 {
				num, err := strconv.Atoi(field.Value[0])
				if err != nil {
					continue
				}
				_, err = l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetCage(num).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "area" && c.Carea == "" {
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetCarea(field.Value[0]).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "birthday" && c.Cbirthday == "" {
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetCbirthday(field.Value[0]).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "birtharea" && c.Cbirtharea == "" {
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetCbirtharea(field.Value[0]).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "idcard_no" && c.CidcardNo == "" {
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetCidcardNo(field.Value[0]).
					Save(l.ctx)
				if err != nil {
					continue
				}
			} else if field.DataIndex == "title" && c.Ctitle == "" {
				_, err := l.svcCtx.DB.Contact.Update().
					Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).
					SetCtitle(field.Value[0]).
					Save(l.ctx)
				if err != nil {
					continue
				}
			}
		} else {
			f, _ := l.svcCtx.DB.ContactField.Query().Where(contactfield.ContactID(c.ID), contactfield.FormID(field.DataIndex)).First(l.ctx)
			if f == nil {
				if field.Value != nil && len(field.Value) > 0 && field.Value[0] != "" {
					_, err := l.svcCtx.DB.ContactField.Create().
						SetContactID(c.ID).
						SetFormID(field.DataIndex).
						SetValue(field.Value).
						Save(l.ctx)
					if err != nil {
						continue
					}
				}
			} else if len(f.Value) == 0 || f.Value[0] == "" {
				if field.Value != nil && len(field.Value) > 0 && field.Value[0] != "" {
					_, err := l.svcCtx.DB.ContactField.UpdateOneID(f.ID).
						SetValue(field.Value).
						Save(l.ctx)
					if err != nil {
						continue
					}
				}
			}
		}
	}
	return nil
}

func ConvertFormData(input []custom_types.ContactFieldTemplate) []FormData {
	result := make([]FormData, len(input))
	for i, item := range input {
		options := make([]FieldPropsOptions, len(item.Options))
		for j, opt := range item.Options {
			options[j] = FieldPropsOptions{
				Label: *opt.Label,
				Value: *opt.Value,
			}
		}
		result[i] = FormData{
			Title:     *item.Label,
			DataIndex: *item.Id,
			ValueType: *item.Type,
			FieldProps: FieldProps{
				Options: options,
			},
		}
	}
	return result
}

func contains(strs []string, target string) bool {
	for _, s := range strs {
		if s == target {
			return true
		}
	}
	return false
}

func parseContent(content string) ([]ResponseItem, error) {
	content = strings.TrimSpace(content)

	// ① 双引号包裹的再来一次："{\"dataIndex\":...}"
	if unq, err := strconv.Unquote(content); err == nil {
		return parseContent(unq) // 尝试递归
	}

	// ② 直接数组形式: [...]
	if strings.HasPrefix(content, "[") {
		var list []ResponseItem
		if err := json.Unmarshal([]byte(content), &list); err == nil {
			return list, nil
		}
	}

	// ③ 对象形式
	if strings.HasPrefix(content, "{") {
		// 3‑1 尝试对象包裹数组: {"values":[...]}
		var wrapper struct {
			Values []ResponseItem `json:"values"`
		}
		if err := json.Unmarshal([]byte(content), &wrapper); err == nil && len(wrapper.Values) > 0 {
			return wrapper.Values, nil
		}

		// 3‑2 尝试单对象形式: {"dataIndex": ...}
		var item ResponseItem
		if err := json.Unmarshal([]byte(content), &item); err == nil {
			return []ResponseItem{item}, nil
		}
	}

	return nil, fmt.Errorf("unsupported content format: %q", content)
}
