package handlers

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/jackc/pgx/v5/pgxpool"
	"ticketing-backend/internal/utils"
)

type UploadHandler struct {
	pool      *pgxpool.Pool
	uploadDir string
}

func NewUploadHandler(pool *pgxpool.Pool, uploadDir string) *UploadHandler {
	return &UploadHandler{pool: pool, uploadDir: uploadDir}
}

func (h *UploadHandler) Upload(c *gin.Context) {
	file, header, err := c.Request.FormFile("file")
	if err != nil {
		utils.BadRequest(c, "File is required")
		return
	}
	defer file.Close()

	// Validate file type
	ext := strings.ToLower(filepath.Ext(header.Filename))
	allowedExts := map[string]bool{".jpg": true, ".jpeg": true, ".png": true, ".gif": true, ".webp": true}
	if !allowedExts[ext] {
		utils.BadRequest(c, "Invalid file type. Allowed: jpg, jpeg, png, gif, webp")
		return
	}

	// Create upload directory
	datePath := time.Now().Format("2006/01/02")
	dir := filepath.Join(h.uploadDir, datePath)
	if err := os.MkdirAll(dir, 0755); err != nil {
		utils.InternalError(c, "Failed to create upload directory")
		return
	}

	// Generate unique filename
	filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), ext)
	filePath := filepath.Join(dir, filename)

	dst, err := os.Create(filePath)
	if err != nil {
		utils.InternalError(c, "Failed to create file")
		return
	}
	defer dst.Close()

	if _, err := io.Copy(dst, file); err != nil {
		utils.InternalError(c, "Failed to save file")
		return
	}

	relativePath := fmt.Sprintf("/uploads/%s/%s", datePath, filename)

	utils.Success(c, gin.H{
		"url":  relativePath,
		"path": filePath,
	})
}

func (h *UploadHandler) ServeUpload(c *gin.Context) {
	path := c.Param("path")
	fullPath := filepath.Join(h.uploadDir, path)

	if _, err := os.Stat(fullPath); os.IsNotExist(err) {
		utils.NotFound(c, "File not found")
		return
	}

	c.File(fullPath)
}
