package admin

import (
	"fmt"
	"log"

	"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 SetupTicketRoutes(r *gin.RouterGroup) {
	tickets := r.Group("/tickets")
	{
		tickets.GET("/stats", handleGetTicketStats)
		tickets.GET("", handleGetTickets)
		tickets.GET("/:id", handleGetTicket)
		tickets.POST("", handleCreateTicket)
		tickets.PUT("/:id", handleUpdateTicket)
		tickets.PUT("/:id/status", handleUpdateTicketStatus)
		tickets.DELETE("/:id", handleDeleteTicket)
		tickets.DELETE("/batch", handleBatchDeleteTickets)
		tickets.GET("/:id/replies", handleGetTicketReplies)
		tickets.POST("/:id/replies", handleCreateTicketReply)
	}
}

func handleGetTicketStats(c *gin.Context) {
	userID := c.GetUint("user_id")
	var total, open, processing, resolved, closed int64

	database.DB.Model(&model.Ticket{}).Where("user_id = ? OR assigned_to = ?", userID, userID).Count(&total)
	database.DB.Model(&model.Ticket{}).Where("(user_id = ? OR assigned_to = ?) AND status = ?", userID, userID, "open").Count(&open)
	database.DB.Model(&model.Ticket{}).Where("(user_id = ? OR assigned_to = ?) AND status = ?", userID, userID, "processing").Count(&processing)
	database.DB.Model(&model.Ticket{}).Where("(user_id = ? OR assigned_to = ?) AND status = ?", userID, userID, "resolved").Count(&resolved)
	database.DB.Model(&model.Ticket{}).Where("(user_id = ? OR assigned_to = ?) AND status = ?", userID, userID, "closed").Count(&closed)

	response.Success(c, gin.H{
		"total_count":      total,
		"open_count":       open,
		"processing_count": processing,
		"resolved_count":   resolved,
		"closed_count":     closed,
	})
}

func handleGetTickets(c *gin.Context) {
	userID := c.GetUint("user_id")
	var tickets []model.Ticket
	if err := database.DB.Where("user_id = ? OR assigned_to = ?", userID, userID).
		Preload("Replies").
		Preload("Application").
		Preload("User").
		Preload("AssignedUser").
		Find(&tickets).Error; err != nil {
		response.Error(c, 500, "获取工单列表失败")
		return
	}

	type TicketWithNames struct {
		model.Ticket
		AppName  string `json:"app_name"`
		UserName string `json:"user_name"`
	}

	var result []TicketWithNames
	for _, ticket := range tickets {
		appName := ""
		if ticket.Application != nil {
			appName = ticket.Application.Name
		}
		userName := ""
		if ticket.User.ID != 0 {
			userName = ticket.User.Username
		}
		result = append(result, TicketWithNames{
			Ticket:   ticket,
			AppName:  appName,
			UserName: userName,
		})
	}

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

func handleGetTicket(c *gin.Context) {
	userID := c.GetUint("user_id")
	id := c.Param("id")
	var ticket model.Ticket
	if err := database.DB.Where("id = ? AND (user_id = ? OR assigned_to = ?)", id, userID, userID).
		Preload("Application").
		Preload("User").
		Preload("AssignedUser").
		First(&ticket).Error; err != nil {
		response.Error(c, 404, "工单不存在")
		return
	}

	type TicketWithNames struct {
		model.Ticket
		AppName  string `json:"app_name"`
		UserName string `json:"user_name"`
	}

	appName := ""
	if ticket.Application != nil {
		appName = ticket.Application.Name
	}
	userName := ""
	if ticket.User.ID != 0 {
		userName = ticket.User.Username
	}

	result := TicketWithNames{
		Ticket:   ticket,
		AppName:  appName,
		UserName: userName,
	}

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

func handleCreateTicket(c *gin.Context) {
	log.Printf("handleCreateTicket called\n")
	userID := c.GetUint("user_id")

	log.Printf("Starting ParseMultipartForm...\n")
	if err := c.Request.ParseMultipartForm(32 << 20); err != nil {
		log.Printf("ParseMultipartForm error: %v\n", err)
		response.Error(c, 400, "解析表单数据失败: "+err.Error())
		return
	}
	log.Printf("ParseMultipartForm succeeded\n")

	ticketType := c.PostForm("type")
	title := c.PostForm("title")
	content := c.PostForm("content")
	priority := c.PostForm("priority")
	applicationIDStr := c.PostForm("application_id")

	log.Printf("Received ticket data - type: '%s', title: '%s', content: '%s', priority: '%s', application_id: '%s'\n",
		ticketType, title, content, priority, applicationIDStr)

	if ticketType == "" {
		ticketType = "system"
	}

	if title == "" {
		log.Printf("Title is empty\n")
		response.Error(c, 400, "标题不能为空")
		return
	}
	if content == "" {
		log.Printf("Content is empty\n")
		response.Error(c, 400, "描述不能为空")
		return
	}
	if priority == "" {
		priority = "normal"
	}

	var applicationID *uint
	if ticketType == "application" && applicationIDStr != "" {
		var appID uint
		if _, err := fmt.Sscanf(applicationIDStr, "%d", &appID); err == nil {
			applicationID = &appID
		}
	}

	ticket := model.Ticket{
		UserID:        userID,
		ApplicationID: applicationID,
		Title:         title,
		Content:       content,
		Category:      "other",
		Priority:      priority,
		Status:        "open",
		Type:          ticketType,
	}

	if applicationID != nil {
		var application model.Application
		if err := database.DB.First(&application, *applicationID).Error; err != nil {
			response.Error(c, 404, "应用不存在")
			return
		}
		ticket.AssignedTo = &application.UserID
	}

	log.Printf("Creating ticket in database...\n")
	if err := database.DB.Create(&ticket).Error; err != nil {
		log.Printf("Create ticket error: %v\n", err)
		response.Error(c, 500, "创建工单失败")
		return
	}
	log.Printf("Ticket created with ID: %d\n", ticket.ID)

	service.LogOperation(c, "create", "ticket", &ticket.ID, fmt.Sprintf("创建工单: %s", ticket.Title), nil)

	log.Printf("Loading ticket details...\n")
	if err := database.DB.Preload("User").Preload("Application").First(&ticket, ticket.ID).Error; err != nil {
		response.Error(c, 500, "获取工单信息失败")
		return
	}

	type TicketWithNames struct {
		model.Ticket
		AppName  string `json:"app_name"`
		UserName string `json:"user_name"`
	}

	appName := ""
	if ticket.Application != nil {
		appName = ticket.Application.Name
	}
	userName := ""
	if ticket.User.ID != 0 {
		userName = ticket.User.Username
	}

	result := TicketWithNames{
		Ticket:   ticket,
		AppName:  appName,
		UserName: userName,
	}

	log.Printf("Returning success response\n")
	response.Success(c, result)
}

func handleUpdateTicket(c *gin.Context) {
	userID := c.GetUint("user_id")
	var req struct {
		Status string `json:"status"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	id := c.Param("id")
	var ticket model.Ticket
	if err := database.DB.Where("id = ? AND user_id = ?", id, userID).First(&ticket).Error; err != nil {
		response.Error(c, 404, "工单不存在")
		return
	}

	ticket.Status = req.Status

	if err := database.DB.Save(&ticket).Error; err != nil {
		response.Error(c, 500, "更新工单失败")
		return
	}

	response.Success(c, ticket)
}

func handleUpdateTicketStatus(c *gin.Context) {
	userID := c.GetUint("user_id")
	var req struct {
		Status string `json:"status"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	id := c.Param("id")
	var ticket model.Ticket
	if err := database.DB.Where("id = ? AND user_id = ?", id, userID).First(&ticket).Error; err != nil {
		response.Error(c, 404, "工单不存在")
		return
	}

	ticket.Status = req.Status

	if err := database.DB.Save(&ticket).Error; err != nil {
		response.Error(c, 500, "更新工单状态失败")
		return
	}

	response.Success(c, ticket)
}

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

	var ticket model.Ticket
	if err := database.DB.Where("id = ? AND (user_id = ? OR assigned_to = ?)", id, userID, userID).First(&ticket).Error; err != nil {
		response.Error(c, 404, "工单不存在")
		return
	}

	if err := database.DB.Delete(&ticket).Error; err != nil {
		response.Error(c, 500, "删除工单失败")
		return
	}

	service.LogOperation(c, "delete", "ticket", &ticket.ID, fmt.Sprintf("删除工单: %s", ticket.Title), nil)

	response.Success(c, nil)
}

func handleBatchDeleteTickets(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 tickets []model.Ticket
	if err := database.DB.Where("id IN ? AND (user_id = ? OR assigned_to = ?)", req.IDs, userID, userID).Find(&tickets).Error; err != nil {
		response.Error(c, 500, "查询工单失败")
		return
	}

	if len(tickets) == 0 {
		response.Error(c, 404, "没有找到可删除的工单")
		return
	}

	var validIDs []uint
	for _, ticket := range tickets {
		validIDs = append(validIDs, ticket.ID)
	}

	if err := database.DB.Where("id IN ?", validIDs).Delete(&model.Ticket{}).Error; err != nil {
		response.Error(c, 500, "批量删除工单失败")
		return
	}

	response.Success(c, gin.H{
		"deleted": len(validIDs),
	})
}

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

	var ticket model.Ticket
	if err := database.DB.Where("id = ? AND user_id = ?", ticketID, userID).First(&ticket).Error; err != nil {
		response.Error(c, 404, "工单不存在")
		return
	}

	var replies []model.TicketReply
	if err := database.DB.Where("ticket_id = ?", ticketID).Preload("User").Order("created_at ASC").Find(&replies).Error; err != nil {
		response.Error(c, 500, "获取回复列表失败")
		return
	}

	response.Success(c, gin.H{
		"replies": replies,
		"total":   len(replies),
	})
}

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

	var ticket model.Ticket
	if err := database.DB.Where("id = ? AND user_id = ?", ticketID, userID).First(&ticket).Error; err != nil {
		response.Error(c, 404, "工单不存在")
		return
	}

	var req struct {
		Content string `json:"content"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	reply := model.TicketReply{
		TicketID: parseUint(ticketID),
		UserID:   userID,
		Content:  req.Content,
	}

	if err := database.DB.Create(&reply).Error; err != nil {
		response.Error(c, 500, "创建回复失败")
		return
	}

	response.Success(c, reply)
}

func parseUint(s string) uint {
	var val uint
	fmt.Sscanf(s, "%d", &val)
	return val
}
