package handlers

import (
	"context"
	"net/http"
	"os"
	"path/filepath"
	"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"
)

const uploadDir = "uploads"

// ListSiteAssets 站点功能模块/上传文件列表
func ListSiteAssets(c *gin.Context) {
	siteID := c.Param("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("site_assets")
	opts := options.Find().SetSort(bson.D{{Key: "created_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.SiteAsset
	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})
}

// UploadSiteAsset 上传功能模块/文件
func UploadSiteAsset(c *gin.Context) {
	siteID := c.Param("site_id")
	if siteID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请提供 site_id"})
		return
	}

	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请选择要上传的文件"})
		return
	}

	baseDir := filepath.Join(uploadDir, "sites", siteID)
	if err := os.MkdirAll(baseDir, 0755); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建目录失败"})
		return
	}

	// 避免覆盖：加时间戳
	name := file.Filename
	ext := filepath.Ext(name)
	nameNoExt := name[:len(name)-len(ext)]
	saveName := nameNoExt + "_" + time.Now().Format("20060102150405") + ext
	relPath := filepath.Join("sites", siteID, saveName)
	destPath := filepath.Join(uploadDir, relPath)

	if err := c.SaveUploadedFile(file, destPath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存文件失败"})
		return
	}

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

	doc := models.SiteAsset{
		SiteID:      siteID,
		Name:        file.Filename,
		FilePath:    relPath,
		Size:        file.Size,
		ContentType: file.Header.Get("Content-Type"),
		CreatedAt:   time.Now().Format(time.RFC3339),
	}
	res, err := config.GetDB(config.DBName).Collection("site_assets").InsertOne(ctx, bson.M{
		"site_id":       doc.SiteID,
		"name":          doc.Name,
		"file_path":     doc.FilePath,
		"size":          doc.Size,
		"content_type":  doc.ContentType,
		"created_at":    doc.CreatedAt,
	})
	if err != nil {
		os.Remove(destPath)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"id": res.InsertedID, "file_path": doc.FilePath, "message": "上传成功"})
}

// DeleteSiteAsset 删除站点资源
func DeleteSiteAsset(c *gin.Context) {
	siteID := c.Param("site_id")
	idStr := c.Param("asset_id")
	if siteID == "" || idStr == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}

	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()

	coll := config.GetDB(config.DBName).Collection("site_assets")
	var asset models.SiteAsset
	err = coll.FindOne(ctx, bson.M{"_id": oid, "site_id": siteID}).Decode(&asset)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "资源不存在"})
		return
	}

	fullPath := filepath.Join(uploadDir, asset.FilePath)
	os.Remove(fullPath)

	_, err = coll.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": "删除成功"})
}
