package article_service

import (
	"bwallet/models"
	"bwallet/pkg/errno"
	"bwallet/pkg/util"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

type Article struct {
	Id         int
	Title      string
	Source     string
	LogoPic    string
	ImgUrl     string
	Content    string
	Top        uint8
	Highlight  uint8
	PlatformId int
	SearchType int

	PageNum  int
	PageSize int
}

func (a *Article) Get() (*models.Article, error) {

	article, err := models.GetOneArticle(a.getMaps())
	if err != nil {
		return nil, err
	}

	if -1 == article.PlatformId {
		/*
			https://iapi.bishijie.com/article/list?app_id=8415d8c1c4f762d8&language=1&page=1&size=20&timestamp=1595918443&sign=3b5f70e637187a9b28d35b4cfccce6b8
		*/

		params := make(map[string]string)
		params["app_id"] = "8415d8c1c4f762d8"
		params["id"] = article.Content
		params["language"] = "1"
		params["timestamp"] = strconv.FormatInt(time.Now().UTC().Unix(), 10)

		req, err := http.NewRequest(http.MethodGet, "https://iapi.bishijie.com/article/detail", nil)
		if err != nil {
			return nil, err
		}
		condition := make(url.Values)
		condition.Add("app_id", params["app_id"])
		condition.Add("id", article.Content)
		condition.Add("language", params["language"])
		condition.Add("timestamp", params["timestamp"])
		sign := util.StringToMd5(condition.Encode() + "09395dc651588c375d066666e072a714")
		condition.Add("sign", sign)

		req.URL.RawQuery = condition.Encode()
		r, err := http.DefaultClient.Do(req)
		if err != nil {
			return nil, err
		}
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			return nil, err
		}
		result := map[string]interface{}{}
		json.Unmarshal(body, &result)

		if _, ok := result["code"]; ok {
			return nil, errno.InternalServerError
		}

		article.Content = result["content"].(string)
	}

	return article, nil
}

func (a *Article) GetAll() ([]*models.Article, error) {
	var article []*models.Article

	article, err := models.GetArticle(a.PageNum, a.PageSize, a.getMaps())
	if err != nil {
		return nil, err
	}

	return article, nil
}

func (a *Article) Add() error {
	article := map[string]interface{}{
		"title":       a.Title,
		"source":      a.Source,
		"logo_pic":    a.LogoPic,
		"img_url":     a.ImgUrl,
		"content":     a.Content,
		"top":         a.Top,
		"highlight":   a.Highlight,
		"platform_id": a.PlatformId,
		"create_time": time.Now().UTC().Unix(),
	}

	if err := models.AddArticle(article); err != nil {
		return err
	}

	return nil
}

func (a *Article) Edit() error {
	return models.EditArticle(a.Id, map[string]interface{}{
		"title":       a.Title,
		"source":      a.Source,
		"logo_pic":    a.LogoPic,
		"img_url":     a.ImgUrl,
		"content":     a.Content,
		"top":         a.Top,
		"highlight":   a.Highlight,
		"platform_id": a.PlatformId,
	})
}

func (a *Article) ExistById() (bool, error) {
	return models.ExistArticleById(a.Id)
}

func (a *Article) Count() (int, error) {
	return models.GetArticleTotal(a.getMaps())
}

func (a *Article) Delete() error {
	return models.DeleteArticle(a.Id)
}

func (a *Article) getMaps() (map[string]interface{}) {
	maps := make(map[string]interface{})

	if a.Id != 0 {
		maps["id"] = a.Id
	}

	if a.Title != "" {
		maps["title"] = a.Title
	}

	if a.PlatformId != 0 {
		maps["platform_id"] = a.PlatformId
	}

	if a.SearchType != 0 {
		platform_id := [] int{a.PlatformId, a.SearchType}
		maps["search_type"] = platform_id
	}

	return maps
}
