/*
 * 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 templaterender

import (
	"math"

	"github.com/apache/answer/internal/service/content"
	questioncommon "github.com/apache/answer/internal/service/question_common"

	"github.com/apache/answer/internal/service/comment"
	"github.com/apache/answer/internal/service/siteinfo_common"
	"github.com/google/wire"

	"github.com/apache/answer/internal/schema"
	"github.com/apache/answer/internal/service/tag"
)

// ProviderSetTemplateRenderController is template render controller providers.
var ProviderSetTemplateRenderController = wire.NewSet(
	NewTemplateRenderController,
)

type TemplateRenderController struct {
	questionService *content.QuestionService
	userService     *content.UserService
	tagService      *tag.TagService
	answerService   *content.AnswerService
	commentService  *comment.CommentService
	siteInfoService siteinfo_common.SiteInfoCommonService
	questionRepo    questioncommon.QuestionRepo
}

func NewTemplateRenderController(
	questionService *content.QuestionService,
	userService *content.UserService,
	tagService *tag.TagService,
	answerService *content.AnswerService,
	commentService *comment.CommentService,
	siteInfoService siteinfo_common.SiteInfoCommonService,
	questionRepo questioncommon.QuestionRepo,
) *TemplateRenderController {
	return &TemplateRenderController{
		questionService: questionService,
		userService:     userService,
		tagService:      tagService,
		answerService:   answerService,
		commentService:  commentService,
		questionRepo:    questionRepo,
		siteInfoService: siteInfoService,
	}
}

// Paginator page
// page : now page
// pageSize : Number per page
// nums : Total
// Returns the contents of the page in the format of 1, 2, 3, 4, and 5. If the contents are less than 5 pages, the page number is returned
func Paginator(page, pageSize int, nums int64) *schema.Paginator {
	if pageSize == 0 {
		pageSize = 10
	}

	var prevpage int // Previous page address
	var nextpage int // Address on the last page
	// Generate the total number of pages based on the total number of nums and the number of prepage pages
	totalpages := int(math.Ceil(float64(nums) / float64(pageSize))) // Total number of Pages
	if page > totalpages {
		page = totalpages
	}
	if page <= 0 {
		page = 1
	}
	var pages []int
	switch {
	case page >= totalpages-5 && totalpages > 5: // The last 5 pages
		start := totalpages - 5 + 1
		prevpage = page - 1
		nextpage = int(math.Min(float64(totalpages), float64(page+1)))
		pages = make([]int, 5)
		for i := range pages {
			pages[i] = start + i
		}
	case page >= 3 && totalpages > 5:
		start := page - 3 + 1
		pages = make([]int, 5)
		for i := range pages {
			pages[i] = start + i
		}
		prevpage = page - 1
		nextpage = page + 1
	default:
		pages = make([]int, int(math.Min(5, float64(totalpages))))
		for i := range pages {
			pages[i] = i + 1
		}
		prevpage = int(math.Max(float64(1), float64(page-1)))
		nextpage = page + 1
	}
	paginator := &schema.Paginator{}
	paginator.Pages = pages
	paginator.Totalpages = totalpages
	paginator.Prevpage = prevpage
	paginator.Nextpage = nextpage
	paginator.Currpage = page
	return paginator
}
