package api

import (
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/tidbcloud/tidb-management-service/tidb-x-migration/internal/task"

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

// Handlers API handlers
type Handlers struct {
	taskManager *task.Manager
}

// NewHandlers creates API handlers instance
func NewHandlers(taskManager *task.Manager) *Handlers {
	return &Handlers{
		taskManager: taskManager,
	}
}

// CreateTask creates a task
func (h *Handlers) CreateTask(c *gin.Context) {
	// Parse request parameters
	var req task.CreateTaskRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "Invalid request parameters: " + err.Error(),
		})
		return
	}

	// Use provided taskId if present, otherwise generate a new one
	taskID := req.TaskId
	if taskID == "" {
		taskID = fmt.Sprintf("task-%d", time.Now().UnixNano()/int64(time.Millisecond))
	}
	if len(taskID) > 120 {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "taskId is too long (max 120 chars)",
		})
		return
	}
	if !isMySQLConnection(req.TaskConnectionOrigin) || !isMySQLConnection(req.TaskConnectionTarget) {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "taskConnectionOrigin/taskConnectionTarget must use mysql:// format",
		})
		return
	}

	// Create task
	t, err := h.taskManager.CreateTask(taskID, req.TaskConnectionOrigin, req.TaskConnectionTarget)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "Failed to create task: " + err.Error(),
		})
		return
	}

	// Return task information
	c.JSON(http.StatusOK, task.TaskResponse{
		ID:               t.ID,
		Status:           string(t.Status),
		ConnectionOrigin: t.ConnectionOrigin,
		ConnectionTarget: t.ConnectionTarget,
		CreatedAt:        t.CreatedAt,
		UpdatedAt:        t.UpdatedAt,
		Error:            t.Error,
		RetryCount:       t.RetryCount,
		Duration:         t.Duration,
	})
}

func isMySQLConnection(conn string) bool {
	return strings.HasPrefix(strings.ToLower(strings.TrimSpace(conn)), "mysql://")
}

// GetTask queries task status
func (h *Handlers) GetTask(c *gin.Context) {
	// Get task ID
	taskID := c.Param("taskId")
	if taskID == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "Task ID cannot be empty",
		})
		return
	}

	// Get task
	t, err := h.taskManager.GetTask(taskID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"error": "Task not found: " + err.Error(),
		})
		return
	}

	// Return task information
	c.JSON(http.StatusOK, task.TaskResponse{
		ID:               t.ID,
		Status:           string(t.Status),
		ConnectionOrigin: t.ConnectionOrigin,
		ConnectionTarget: t.ConnectionTarget,
		CreatedAt:        t.CreatedAt,
		UpdatedAt:        t.UpdatedAt,
		Error:            t.Error,
		RetryCount:       t.RetryCount,
		Duration:         t.Duration,
	})
}
