package handler

import (
	"fmt"
	"net/http"
	"path/filepath"
	"strings"

	"ci/internal/service"

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

// UploadHandler handles file upload endpoints.
type UploadHandler struct {
	Svc *service.ProjectService
}

func NewUploadHandler(svc *service.ProjectService) *UploadHandler {
	return &UploadHandler{Svc: svc}
}

// UploadFiles handles source file upload for a project (zip/tar.gz).
func (h *UploadHandler) UploadFiles(c *gin.Context) {
	id, err := parseID(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project id"})
		return
	}

	// Verify project exists and is upload mode
	project, err := h.Svc.GetProject(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "project not found"})
		return
	}

	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "no file provided"})
		return
	}

	// Validate file extension
	ext := strings.ToLower(filepath.Ext(file.Filename))
	valid := false
	if ext == ".zip" {
		valid = true
	}
	if strings.HasSuffix(strings.ToLower(file.Filename), ".tar.gz") || strings.HasSuffix(strings.ToLower(file.Filename), ".tgz") {
		valid = true
	}

	if !valid {
		c.JSON(http.StatusBadRequest, gin.H{"error": "only .zip and .tar.gz files are supported"})
		return
	}

	// Save uploaded file to temp location
	tmpPath := filepath.Join(h.Svc.Workspace.ProjectDir(project.ID), file.Filename)
	if err := c.SaveUploadedFile(file, tmpPath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to save file: %v", err)})
		return
	}

	// Extract to src directory
	if err := h.Svc.Workspace.ExtractArchive(project.ID, tmpPath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to extract: %v", err)})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":  "file uploaded and extracted successfully",
		"filename": file.Filename,
	})
}
