package admin

import (
	"fmt"
	"log"
	"strconv"

	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
	"verification-platform-backend/internal/service"
	"verification-platform-backend/pkg/response"

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

func SetupAnnouncementRoutes(r *gin.RouterGroup) {
	announcements := r.Group("/announcements")
	{
		announcements.GET("", handleGetAllAnnouncements)
		announcements.GET("/:id", handleGetAnnouncementByID)
		announcements.DELETE("/batch", handleBatchDeleteAnnouncements)
	}
}

func handleGetAllAnnouncements(c *gin.Context) {
	userID := c.GetUint("user_id")
	log.Printf("[DEBUG] handleGetAllAnnouncements called, userID: %d\n", userID)

	page := c.DefaultQuery("page", "1")
	pageSize := c.DefaultQuery("page_size", "20")

	var total int64

	var userApps []model.Application
	if err := database.DB.Where("user_id = ?", userID).Find(&userApps).Error; err != nil {
		response.Error(c, 500, "获取应用列表失败")
		return
	}

	log.Printf("[DEBUG] Found %d user apps\n", len(userApps))
	for i, app := range userApps {
		log.Printf("[DEBUG] App %d: ID=%d, Name=%s\n", i, app.ID, app.Name)
	}

	if len(userApps) == 0 {
		response.Success(c, gin.H{
			"announcements": []interface{}{},
			"total":         0,
		})
		return
	}

	appIDs := make([]uint, len(userApps))
	appNameMap := make(map[uint]string)
	for i, app := range userApps {
		appIDs[i] = app.ID
		appNameMap[app.ID] = app.Name
	}

	log.Printf("[DEBUG] appNameMap: %v\n", appNameMap)

	database.DB.Model(&model.Announcement{}).Where("application_id IN ?", appIDs).Count(&total)

	var announcements []model.Announcement
	offset := 0
	if pageInt, err := strconv.Atoi(page); err == nil && pageInt > 1 {
		offset = (pageInt - 1) * 20
	}

	limit := 20
	if pageSizeInt, err := strconv.Atoi(pageSize); err == nil && pageSizeInt > 0 {
		limit = pageSizeInt
	}

	if err := database.DB.Where("application_id IN ?", appIDs).Order("is_top DESC, created_at DESC").Limit(limit).Offset(offset).Find(&announcements).Error; err != nil {
		response.Error(c, 500, "获取公告列表失败")
		return
	}

	log.Printf("[DEBUG] Found %d announcements\n", len(announcements))
	for i, a := range announcements {
		log.Printf("[DEBUG] Announcement %d: ID=%d, ApplicationID=%d, Title=%s\n", i, a.ID, a.ApplicationID, a.Title)
	}

	type AnnouncementWithAppName struct {
		model.Announcement
		ApplicationName string `json:"application_name"`
	}

	result := make([]AnnouncementWithAppName, len(announcements))
	for i, a := range announcements {
		appName := appNameMap[a.ApplicationID]
		result[i] = AnnouncementWithAppName{
			Announcement:    a,
			ApplicationName: appName,
		}
	}

	response.Success(c, gin.H{
		"announcements": result,
		"total":         total,
	})
}

func handleGetAnnouncementByID(c *gin.Context) {
	userID := c.GetUint("user_id")
	announcementID := c.Param("id")

	var userApps []model.Application
	if err := database.DB.Where("user_id = ?", userID).Find(&userApps).Error; err != nil {
		response.Error(c, 500, "获取应用列表失败")
		return
	}

	appIDs := make([]uint, len(userApps))
	appNameMap := make(map[uint]string)
	for i, app := range userApps {
		appIDs[i] = app.ID
		appNameMap[app.ID] = app.Name
	}

	var announcement model.Announcement
	if err := database.DB.Where("id = ? AND application_id IN ?", announcementID, appIDs).First(&announcement).Error; err != nil {
		response.Error(c, 404, "公告不存在")
		return
	}

	response.Success(c, gin.H{
		"id":              announcement.ID,
		"application_id":  announcement.ApplicationID,
		"application_name": appNameMap[announcement.ApplicationID],
		"title":           announcement.Title,
		"content":         announcement.Content,
		"type":            announcement.Type,
		"status":          announcement.Status,
		"is_top":          announcement.IsTop,
		"created_at":      announcement.CreatedAt,
		"updated_at":      announcement.UpdatedAt,
	})
}

func handleBatchDeleteAnnouncements(c *gin.Context) {
	userID := c.GetUint("user_id")

	var req struct {
		IDs []uint `json:"ids"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	if len(req.IDs) == 0 {
		response.Error(c, 400, "请选择要删除的公告")
		return
	}

	var userApps []model.Application
	if err := database.DB.Where("user_id = ?", userID).Find(&userApps).Error; err != nil {
		response.Error(c, 500, "获取应用列表失败")
		return
	}

	appIDs := make([]uint, len(userApps))
	for i, app := range userApps {
		appIDs[i] = app.ID
	}

	var announcements []model.Announcement
	if err := database.DB.Where("id IN ? AND application_id IN ?", req.IDs, appIDs).Find(&announcements).Error; err != nil {
		response.Error(c, 500, "获取公告失败")
		return
	}

	for _, announcement := range announcements {
		for _, app := range userApps {
			if app.ID == announcement.ApplicationID && service.GetApplicationDisabledStatus(app.ID) {
				response.Error(c, 403, fmt.Sprintf("应用 %s 已被禁用，无法删除其公告", app.Name))
				return
			}
		}
	}

	if err := database.DB.Where("id IN ? AND application_id IN ?", req.IDs, appIDs).Delete(&model.Announcement{}).Error; err != nil {
		response.Error(c, 500, "批量删除公告失败")
		return
	}

	response.Success(c, nil)
}
