package api

import (
	"fmt"
	"licserver/internal/service"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

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

type UploadHandler struct {
	uploadService *service.UploadService
}

func NewUploadHandler(uploadService *service.UploadService) *UploadHandler {
	return &UploadHandler{uploadService: uploadService}
}

func (h *UploadHandler) UploadFile(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未找到上传文件"})
		return
	}

	deviceUID := c.PostForm("device_uid")
	description := c.PostForm("description")
	userID := c.GetUint("userID")

	upload, err := h.uploadService.UploadFile(file, userID, deviceUID, description)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, upload)
}

func (h *UploadHandler) DownloadFile(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件ID"})
		return
	}

	file, err := h.uploadService.DownloadFile(uint(id))
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
		return
	}

	c.FileAttachment(file.FilePath, file.FileName)
}

func (h *UploadHandler) DeleteFile(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件ID"})
		return
	}

	userID := c.GetUint("userID")
	if err := h.uploadService.DeleteFile(uint(id), userID); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "文件删除成功"})
}

func (h *UploadHandler) GetDeviceFiles(c *gin.Context) {
	deviceUID := c.Param("uid")
	files, err := h.uploadService.GetDeviceFiles(deviceUID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, files)
}

func (h *UploadHandler) UploadChunk(c *gin.Context) {
	file, err := c.FormFile("chunk")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未找到上传文件"})
		return
	}

	fileHash := c.PostForm("fileHash")
	if fileHash == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未提供文件哈希"})
		return
	}

	chunkNumber, err := strconv.Atoi(c.PostForm("chunkNumber"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的分片序号"})
		return
	}

	totalChunks, err := strconv.Atoi(c.PostForm("totalChunks"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的总分片数"})
		return
	}

	totalSize, err := strconv.ParseInt(c.PostForm("totalSize"), 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件大小"})
		return
	}

	filename := c.PostForm("filename")
	deviceUID := c.PostForm("deviceUID")
	userID := c.GetUint("userID")

	err = h.uploadService.UploadChunk(
		file,
		fileHash,
		chunkNumber,
		totalChunks,
		totalSize,
		filename,
		userID,
		deviceUID,
	)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 检查是否所有分片都已上传
	completed, err := h.uploadService.CheckUploadStatus(fileHash)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":   "分片上传成功",
		"completed": completed,
	})
}

func (h *UploadHandler) MergeChunks(c *gin.Context) {
	fileHash := c.PostForm("fileHash")
	if fileHash == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未提供文件哈希"})
		return
	}

	upload, err := h.uploadService.MergeChunks(fileHash)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "文件合并成功",
		"file":    upload,
	})
}

func (h *UploadHandler) UploadSiteFile(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未找到上传文件"})
		return
	}

	// 检查文件类型
	ext := strings.ToLower(filepath.Ext(file.Filename))
	allowedExts := map[string]bool{
		".jpg": true, ".jpeg": true, ".png": true, ".gif": true,
		".ico": true, ".svg": true,
	}
	if !allowedExts[ext] {
		c.JSON(http.StatusBadRequest, gin.H{"error": "不支持的文件类型"})
		return
	}

	// 生成文件名
	filename := fmt.Sprintf("site_%s%s", time.Now().Format("20060102150405"), ext)

	// 构建目标目录路径
	uploadDir := filepath.Join("web", "static", "images")
	if err := os.MkdirAll(uploadDir, 0755); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建目录失败"})
		return
	}

	// 构建完整的文件路径
	filePath := filepath.Join(uploadDir, filename)

	// 保存文件
	if err := c.SaveUploadedFile(file, filePath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存文件失败"})
		return
	}

	// 返回文件URL（使用正斜杠作为URL路径分隔符）
	fileURL := "/" + strings.Join([]string{"static", "images", filename}, "/")
	c.JSON(http.StatusOK, gin.H{
		"url":     fileURL,
		"message": "文件上传成功",
	})
}
