/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package migrations

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"xorm.io/builder"

	"github.com/apache/answer/internal/base/constant"
	"github.com/apache/answer/internal/entity"
	"github.com/apache/answer/internal/schema"
	"github.com/apache/answer/internal/service/permission"
	"github.com/segmentfault/pacman/log"
	"xorm.io/xorm"
)

func updateCount(ctx context.Context, x *xorm.Engine) error {
	fns := []func(ctx context.Context, x *xorm.Engine) error{
		inviteAnswer,
		addPrivilegeForInviteSomeoneToAnswer,
		addGravatarBaseURL,
		updateQuestionCount,
		updateTagCount,
		updateUserQuestionCount,
		updateUserAnswerCount,
		inBoxData,
	}
	for _, fn := range fns {
		if err := fn(ctx, x); err != nil {
			return err
		}
	}
	return nil
}

func addGravatarBaseURL(ctx context.Context, x *xorm.Engine) error {
	usersSiteInfo := &entity.SiteInfo{
		Type: constant.SiteTypeUsers,
	}
	exist, err := x.Context(ctx).Get(usersSiteInfo)
	if err != nil {
		return fmt.Errorf("get config failed: %w", err)
	}
	if exist {
		content := &schema.SiteUsersReq{}
		_ = json.Unmarshal([]byte(usersSiteInfo.Content), content)
		content.GravatarBaseURL = "https://www.gravatar.com/avatar/"
		data, _ := json.Marshal(content)
		usersSiteInfo.Content = string(data)

		_, err = x.Context(ctx).ID(usersSiteInfo.ID).Cols("content").Update(usersSiteInfo)
		if err != nil {
			return fmt.Errorf("update site info failed: %w", err)
		}
	}
	return nil
}

func addPrivilegeForInviteSomeoneToAnswer(ctx context.Context, x *xorm.Engine) error {
	// add rank for invite to answer
	powers := []*entity.Power{
		{ID: 38, Name: "invite someone to answer", PowerType: permission.AnswerInviteSomeoneToAnswer, Description: "invite someone to answer"},
	}
	for _, power := range powers {
		exist, err := x.Context(ctx).Get(&entity.Power{PowerType: power.PowerType})
		if err != nil {
			return err
		}
		if exist {
			_, err = x.Context(ctx).ID(power.ID).Update(power)
		} else {
			_, err = x.Context(ctx).Insert(power)
		}
		if err != nil {
			return err
		}
	}
	rolePowerRels := []*entity.RolePowerRel{
		{RoleID: 2, PowerType: permission.AnswerInviteSomeoneToAnswer},
		{RoleID: 3, PowerType: permission.AnswerInviteSomeoneToAnswer},
	}
	for _, rel := range rolePowerRels {
		exist, err := x.Context(ctx).Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType})
		if err != nil {
			return err
		}
		if exist {
			continue
		}
		_, err = x.Context(ctx).Insert(rel)
		if err != nil {
			return err
		}
	}

	defaultConfigTable := []*entity.Config{
		{ID: 127, Key: "rank.answer.invite_someone_to_answer", Value: `1000`},
	}
	for _, c := range defaultConfigTable {
		exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID})
		if err != nil {
			return fmt.Errorf("get config failed: %w", err)
		}
		if exist {
			if _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil {
				return fmt.Errorf("update config failed: %w", err)
			}
			continue
		}
		if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil {
			return fmt.Errorf("add config failed: %w", err)
		}
	}
	return nil
}

func updateQuestionCount(ctx context.Context, x *xorm.Engine) error {
	// question answer count
	answers := make([]AnswerV13, 0)
	err := x.Context(ctx).Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable})
	if err != nil {
		return fmt.Errorf("get answers failed: %w", err)
	}
	questionAnswerCount := make(map[string]int)
	for _, answer := range answers {
		_, ok := questionAnswerCount[answer.QuestionID]
		if !ok {
			questionAnswerCount[answer.QuestionID] = 1
		} else {
			questionAnswerCount[answer.QuestionID]++
		}
	}
	questionList := make([]QuestionV13, 0)
	err = x.Context(ctx).Find(&questionList, &QuestionV13{})
	if err != nil {
		return fmt.Errorf("get questions failed: %w", err)
	}
	for _, item := range questionList {
		_, ok := questionAnswerCount[item.ID]
		if ok {
			item.AnswerCount = questionAnswerCount[item.ID]
			if _, err = x.Context(ctx).Cols("answer_count").Update(item, &QuestionV13{ID: item.ID}); err != nil {
				log.Errorf("update %+v config failed: %s", item, err)
				return fmt.Errorf("update question failed: %w", err)
			}
		}
	}

	return nil
}

// updateTagCount update tag count
func updateTagCount(ctx context.Context, x *xorm.Engine) error {
	tagRelList := make([]entity.TagRel, 0)
	err := x.Context(ctx).Find(&tagRelList, &entity.TagRel{})
	if err != nil {
		return fmt.Errorf("get tag rel failed: %w", err)
	}
	questionIDs := make([]string, 0)
	questionsAvailableMap := make(map[string]bool)
	questionsHideMap := make(map[string]bool)
	for _, item := range tagRelList {
		questionIDs = append(questionIDs, item.ObjectID)
		questionsAvailableMap[item.ObjectID] = false
		questionsHideMap[item.ObjectID] = false
	}
	questionList := make([]QuestionV13, 0)
	err = x.Context(ctx).In("id", questionIDs).And(builder.Lt{"question.status": entity.QuestionStatusDeleted}).Find(&questionList, &QuestionV13{})
	if err != nil {
		return fmt.Errorf("get questions failed: %w", err)
	}
	for _, question := range questionList {
		_, ok := questionsAvailableMap[question.ID]
		if ok {
			questionsAvailableMap[question.ID] = true
			if question.Show == entity.QuestionHide {
				questionsHideMap[question.ID] = true
			}
		}
	}

	for id, ok := range questionsHideMap {
		if ok {
			if _, err = x.Context(ctx).Cols("status").Update(&entity.TagRel{Status: entity.TagRelStatusHide}, &entity.TagRel{ObjectID: id}); err != nil {
				log.Errorf("update %+v config failed: %s", id, err)
			}
		}
	}

	for id, ok := range questionsAvailableMap {
		if !ok {
			if _, err = x.Context(ctx).Cols("status").Update(&entity.TagRel{Status: entity.TagRelStatusDeleted}, &entity.TagRel{ObjectID: id}); err != nil {
				log.Errorf("update %+v config failed: %s", id, err)
			}
		}
	}

	// select tag count
	newTagRelList := make([]entity.TagRel, 0)
	err = x.Context(ctx).Find(&newTagRelList, &entity.TagRel{Status: entity.TagRelStatusAvailable})
	if err != nil {
		return fmt.Errorf("get tag rel failed: %w", err)
	}
	tagCountMap := make(map[string]int)
	for _, v := range newTagRelList {
		_, ok := tagCountMap[v.TagID]
		if !ok {
			tagCountMap[v.TagID] = 1
		} else {
			tagCountMap[v.TagID]++
		}
	}
	TagList := make([]entity.Tag, 0)
	err = x.Context(ctx).Find(&TagList, &entity.Tag{})
	if err != nil {
		return fmt.Errorf("get tag  failed: %w", err)
	}
	for _, tag := range TagList {
		_, ok := tagCountMap[tag.ID]
		if ok {
			tag.QuestionCount = tagCountMap[tag.ID]
			if _, err = x.Context(ctx).Update(tag, &entity.Tag{ID: tag.ID}); err != nil {
				log.Errorf("update %+v tag failed: %s", tag.ID, err)
				return fmt.Errorf("update tag failed: %w", err)
			}
		} else {
			tag.QuestionCount = 0
			if _, err = x.Context(ctx).Cols("question_count").Update(tag, &entity.Tag{ID: tag.ID}); err != nil {
				log.Errorf("update %+v tag failed: %s", tag.ID, err)
				return fmt.Errorf("update tag failed: %w", err)
			}
		}
	}
	return nil
}

// updateUserQuestionCount update user question count
func updateUserQuestionCount(ctx context.Context, x *xorm.Engine) error {
	questionList := make([]QuestionV13, 0)
	err := x.Context(ctx).Where(builder.Lt{"status": entity.QuestionStatusDeleted}).Find(&questionList, &QuestionV13{})
	if err != nil {
		return fmt.Errorf("get question  failed: %w", err)
	}
	userQuestionCountMap := make(map[string]int)
	for _, question := range questionList {
		_, ok := userQuestionCountMap[question.UserID]
		if !ok {
			userQuestionCountMap[question.UserID] = 1
		} else {
			userQuestionCountMap[question.UserID]++
		}
	}
	userList := make([]entity.User, 0)
	err = x.Context(ctx).Find(&userList, &entity.User{})
	if err != nil {
		return fmt.Errorf("get user  failed: %w", err)
	}
	for _, user := range userList {
		_, ok := userQuestionCountMap[user.ID]
		if ok {
			user.QuestionCount = userQuestionCountMap[user.ID]
			if _, err = x.Context(ctx).Cols("question_count").Update(user, &entity.User{ID: user.ID}); err != nil {
				log.Errorf("update %+v user failed: %s", user.ID, err)
				return fmt.Errorf("update user failed: %w", err)
			}
		} else {
			user.QuestionCount = 0
			if _, err = x.Context(ctx).Cols("question_count").Update(user, &entity.User{ID: user.ID}); err != nil {
				log.Errorf("update %+v user failed: %s", user.ID, err)
				return fmt.Errorf("update user failed: %w", err)
			}
		}
	}
	return nil
}

type AnswerV13 struct {
	ID         string `xorm:"not null pk autoincr BIGINT(20) id"`
	QuestionID string `xorm:"not null default 0 BIGINT(20) question_id"`
	UserID     string `xorm:"not null default 0 BIGINT(20) INDEX user_id"`
	Status     int    `xorm:"not null default 1 INT(11) status"`
	Accepted   int    `xorm:"not null default 1 INT(11) adopted"`
}

func (AnswerV13) TableName() string {
	return "answer"
}

// updateUserAnswerCount update user answer count
func updateUserAnswerCount(ctx context.Context, x *xorm.Engine) error {
	answers := make([]AnswerV13, 0)
	err := x.Context(ctx).Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable})
	if err != nil {
		return fmt.Errorf("get answers failed: %w", err)
	}
	userAnswerCount := make(map[string]int)
	for _, answer := range answers {
		_, ok := userAnswerCount[answer.UserID]
		if !ok {
			userAnswerCount[answer.UserID] = 1
		} else {
			userAnswerCount[answer.UserID]++
		}
	}
	userList := make([]entity.User, 0)
	err = x.Context(ctx).Find(&userList, &entity.User{})
	if err != nil {
		return fmt.Errorf("get user failed: %w", err)
	}
	for _, user := range userList {
		_, ok := userAnswerCount[user.ID]
		if ok {
			user.AnswerCount = userAnswerCount[user.ID]
			if _, err = x.Context(ctx).Cols("answer_count").Update(user, &entity.User{ID: user.ID}); err != nil {
				log.Errorf("update %+v user failed: %s", user.ID, err)
				return fmt.Errorf("update user failed: %w", err)
			}
		} else {
			user.AnswerCount = 0
			if _, err = x.Context(ctx).Cols("answer_count").Update(user, &entity.User{ID: user.ID}); err != nil {
				log.Errorf("update %+v user failed: %s", user.ID, err)
				return fmt.Errorf("update user failed: %w", err)
			}
		}
	}
	return nil
}

type QuestionV13 struct {
	ID               string    `xorm:"not null pk BIGINT(20) id"`
	CreatedAt        time.Time `xorm:"not null default CURRENT_TIMESTAMP TIMESTAMP created_at"`
	UpdatedAt        time.Time `xorm:"updated_at TIMESTAMP"`
	UserID           string    `xorm:"not null default 0 BIGINT(20) INDEX user_id"`
	InviteUserID     string    `xorm:"TEXT invite_user_id"`
	LastEditUserID   string    `xorm:"not null default 0 BIGINT(20) last_edit_user_id"`
	Title            string    `xorm:"not null default '' VARCHAR(150) title"`
	OriginalText     string    `xorm:"not null MEDIUMTEXT original_text"`
	ParsedText       string    `xorm:"not null MEDIUMTEXT parsed_text"`
	Status           int       `xorm:"not null default 1 INT(11) status"`
	Pin              int       `xorm:"not null default 1 INT(11) pin"`
	Show             int       `xorm:"not null default 1 INT(11) show"`
	ViewCount        int       `xorm:"not null default 0 INT(11) view_count"`
	UniqueViewCount  int       `xorm:"not null default 0 INT(11) unique_view_count"`
	VoteCount        int       `xorm:"not null default 0 INT(11) vote_count"`
	AnswerCount      int       `xorm:"not null default 0 INT(11) answer_count"`
	CollectionCount  int       `xorm:"not null default 0 INT(11) collection_count"`
	FollowCount      int       `xorm:"not null default 0 INT(11) follow_count"`
	AcceptedAnswerID string    `xorm:"not null default 0 BIGINT(20) accepted_answer_id"`
	LastAnswerID     string    `xorm:"not null default 0 BIGINT(20) last_answer_id"`
	PostUpdateTime   time.Time `xorm:"post_update_time TIMESTAMP"`
	RevisionID       string    `xorm:"not null default 0 BIGINT(20) revision_id"`
}

func (QuestionV13) TableName() string {
	return "question"
}

func inviteAnswer(ctx context.Context, x *xorm.Engine) error {
	err := x.Context(ctx).Sync(new(QuestionV13))
	if err != nil {
		return err
	}
	return nil
}

// inBoxData Classify messages
func inBoxData(ctx context.Context, x *xorm.Engine) error {
	type Notification struct {
		ID        string    `xorm:"not null pk autoincr BIGINT(20) id"`
		CreatedAt time.Time `xorm:"created TIMESTAMP created_at"`
		UpdatedAt time.Time `xorm:"TIMESTAMP updated_at"`
		UserID    string    `xorm:"not null default 0 BIGINT(20) INDEX user_id"`
		ObjectID  string    `xorm:"not null default 0 INDEX BIGINT(20) object_id"`
		Content   string    `xorm:"not null TEXT content"`
		Type      int       `xorm:"not null default 0 INT(11) type"`
		MsgType   int       `xorm:"not null default 0 INT(11) msg_type"`
		IsRead    int       `xorm:"not null default 1 INT(11) is_read"`
		Status    int       `xorm:"not null default 1 INT(11) status"`
	}
	err := x.Context(ctx).Sync(new(Notification))
	if err != nil {
		return err
	}
	msglist := make([]entity.Notification, 0)
	err = x.Context(ctx).Find(&msglist, &entity.Notification{})
	if err != nil {
		return fmt.Errorf("get Notification failed: %w", err)
	}
	for _, v := range msglist {
		Content := &schema.NotificationContent{}
		err := json.Unmarshal([]byte(v.Content), Content)
		if err != nil {
			continue
		}
		_, ok := constant.NotificationMsgTypeMapping[Content.NotificationAction]
		if ok {
			v.MsgType = constant.NotificationMsgTypeMapping[Content.NotificationAction]
			if _, err = x.Context(ctx).Update(v, &entity.Notification{ID: v.ID}); err != nil {
				log.Errorf("update %+v Notification failed: %s", v.ID, err)
			}
		}
	}

	return nil
}
