package handlers

import (
	"context"
	"net/http"
	"time"

	"go.mongodb.org/mongo-driver/v2/bson"
	"go.mongodb.org/mongo-driver/v2/mongo/options"

	"yh_web/server/config"
	"yh_web/server/models"

	"github.com/gin-gonic/gin"
)

// GetPages 网页列表（按站点）
func GetPages(c *gin.Context) {
	siteID := c.Query("site_id")
	if siteID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请提供 site_id"})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	coll := config.GetDB(config.DBName).Collection("pages")
	opts := options.Find().SetSort(bson.D{{Key: "updated_at", Value: -1}})
	cursor, err := coll.Find(ctx, bson.M{"site_id": siteID}, opts)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer cursor.Close(ctx)

	var list []models.Page
	if err = cursor.All(ctx, &list); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	total, _ := coll.CountDocuments(ctx, bson.M{"site_id": siteID})

	c.JSON(http.StatusOK, gin.H{"list": list, "total": total})
}

// GetPageByID 单页
func GetPageByID(c *gin.Context) {
	idStr := c.Param("id")
	oid, err := bson.ObjectIDFromHex(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的页面ID"})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	var page models.Page
	err = config.GetDB(config.DBName).Collection("pages").FindOne(ctx, bson.M{"_id": oid}).Decode(&page)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "页面不存在"})
		return
	}
	c.JSON(http.StatusOK, page)
}

// CreatePageInput 创建网页
type CreatePageInput struct {
	SiteID  string `json:"site_id" binding:"required"`
	Slug    string `json:"slug" binding:"required"`
	Title   string `json:"title" binding:"required"`
	Type    string `json:"type"`   // homepage, page
	Content string `json:"content"`
}

// CreatePage 创建网页
func CreatePage(c *gin.Context) {
	var input CreatePageInput
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请填写 site_id、slug、title"})
		return
	}
	if input.Type == "" {
		input.Type = "page"
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	coll := config.GetDB(config.DBName).Collection("pages")
	now := time.Now().Format(time.RFC3339)
	doc := bson.M{
		"site_id":    input.SiteID,
		"slug":       input.Slug,
		"title":      input.Title,
		"type":       input.Type,
		"content":    input.Content,
		"updated_at": now,
	}
	res, err := coll.InsertOne(ctx, doc)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"id": res.InsertedID, "message": "创建成功"})
}

// UpdatePageInput 更新网页
type UpdatePageInput struct {
	Slug    *string `json:"slug"`
	Title   *string `json:"title"`
	Type    *string `json:"type"`
	Content *string `json:"content"`
}

// UpdatePage 更新网页
func UpdatePage(c *gin.Context) {
	idStr := c.Param("id")
	oid, err := bson.ObjectIDFromHex(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的页面ID"})
		return
	}

	var input UpdatePageInput
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	set := bson.M{"updated_at": time.Now().Format(time.RFC3339)}
	if input.Slug != nil {
		set["slug"] = *input.Slug
	}
	if input.Title != nil {
		set["title"] = *input.Title
	}
	if input.Type != nil {
		set["type"] = *input.Type
	}
	if input.Content != nil {
		set["content"] = *input.Content
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	_, err = config.GetDB(config.DBName).Collection("pages").UpdateOne(ctx, bson.M{"_id": oid}, bson.M{"$set": set})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "更新成功"})
}

// DeletePage 删除网页
func DeletePage(c *gin.Context) {
	idStr := c.Param("id")
	oid, err := bson.ObjectIDFromHex(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的页面ID"})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	_, err = config.GetDB(config.DBName).Collection("pages").DeleteOne(ctx, bson.M{"_id": oid})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}
