package api

import (
	"baishuihu/db/model"
	"baishuihu/db/repo"
	"baishuihu/log"
	"errors"
	"fmt"
	"regexp"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

func Article(r *GinRouter) {
	r.POSTJWT("/article/create", CreateArticle)
	r.POSTJWT("/article/delete/:id", DeleteArticle)
	r.GET("/article/list", ArticleList)
	r.GET("/article/detail/:id", ArticleDetail)
	r.POSTJWT("/article/update", UpdateArticle)
	r.GET("/article/search", ArticleSearch)

}

var ArticleProjects []string = []string{"_id", "cid", "title", "type", "cover", "summary", "createTime", "updateTime"}

func CreateArticle(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var article model.Article
	err := c.ShouldBindJSON(&article)
	if err != nil {
		log.Error(err)
		return nil, err
	}
	article.CreateTime = time.Now()
	article.UpdateTime = time.Now()
	return repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionArticle, &article)
}

func DeleteArticle(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	_id := c.Param("id")
	id, _ := primitive.ObjectIDFromHex(_id)
	if id.IsZero() {
		return nil, errors.New("id错误")
	}
	return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionArticle, _id)
}

func ArticleList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	page, size, query := UtilQueryPageSize(c)
	if v, ok := query["cid"]; ok {
		query["cid"], _ = primitive.ObjectIDFromHex(v.(string))
	}
	fmt.Println(query)
	return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
		CollectName: repo.CollectionArticle,
		Page:        page,
		Size:        size,
		Query:       query,
		Project:     ArticleProjects,
		Sort:        bson.D{bson.E{Key: "sort", Value: 1}, bson.E{Key: "createTime", Value: -1}},
	})
}

func ArticleDetail(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	_id := c.Param("id")
	idType := c.Query("type")

	id, _ := primitive.ObjectIDFromHex(_id)
	if id.IsZero() {
		return nil, errors.New("id错误")
	}
	query := repo.Map{"_id": id}
	if idType == "category" {
		delete(query, "_id")
		query["cid"] = id
	}
	article := &model.Article{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionArticle,
		Query:       query,
	}, article)
	if err != nil {
		log.Error(err)
		return nil, err
	}

	if !found {
		return nil, errors.New("未找到该数据")
	}
	return article, nil
}

func UpdateArticle(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var article model.Article
	err := c.ShouldBindJSON(&article)
	if err != nil {
		log.Error(err)
		return nil, err
	}
	if article.Id.IsZero() {
		return nil, errors.New("id错误")
	}
	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionArticle, article.Id.Hex(), &article)
}

// 根据关键字搜索符合条件的title/summary的文章
func ArticleSearch(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	page, size, query := UtilQueryPageSize(c)
	fmt.Println(query)
	if v, ok := query["key"]; ok {
		delete(query, "key")
		// 搜索特殊字符
		re := regexp.MustCompile(`[*\+\.\-\?\^\$\[\]]`)
		key := strings.TrimSpace(re.ReplaceAllString(v.(string), `\$0`))
		fmt.Println(key)
		if len(key) > 0 {
			// searchQuery := bson.A{}
			// searchQuery = append(searchQuery, bson.M{"title": bson.M{"$regex": key}})
			// searchQuery = append(searchQuery, bson.M{"summary": bson.M{"$regex": key}})
			// query["$or"] = searchQuery
			query["title"] = bson.M{"$regex": key}
		}

	}
	result, err := repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
		CollectName: repo.CollectionArticle,
		Page:        page,
		Size:        size,
		Query:       query,
		Project:     ArticleProjects,
		Sort:        bson.D{bson.E{Key: "sort", Value: 1}, bson.E{Key: "createTime", Value: -1}},
	})
	if err != nil {
		return nil, errors.New("查询字符不正确")
	}
	return result, err
}
