package controllers

import (
	"net/http"

	"ems-backend/models"
	"ems-backend/services"

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

type BackupController struct{}

func (bc *BackupController) GetConfig(c *gin.Context) {
	config, err := services.GlobalBackupService.GetConfig()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"data": config})
}

func (bc *BackupController) SaveConfig(c *gin.Context) {
	var config models.BackupConfig
	if err := c.ShouldBindJSON(&config); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := services.GlobalBackupService.SaveConfig(&config); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "Configuration saved"})
}

func (bc *BackupController) ManualBackup(c *gin.Context) {
	// Execute both backups asynchronously
	go func() {
		services.GlobalBackupService.PerformBackup()
		services.GlobalBackupService.PerformResourceBackup()
	}()
	c.JSON(http.StatusOK, gin.H{"message": "Full backup started (Database & Resources)"})
}

func (bc *BackupController) GetLogs(c *gin.Context) {
	logs, err := services.GlobalBackupService.GetLogs()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"data": logs})
}

func (bc *BackupController) TestConnection(c *gin.Context) {
	var config models.BackupConfig
	if err := c.ShouldBindJSON(&config); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := services.GlobalBackupService.TestConnection(&config); err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"success": true, "message": "Connection successful"})
}

func (bc *BackupController) Download(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "ID required"})
		return
	}

	object, fileName, err := services.GlobalBackupService.DownloadFile(id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer object.Close()

	// Set headers
	c.Header("Content-Description", "File Transfer")
	c.Header("Content-Transfer-Encoding", "binary")
	c.Header("Content-Disposition", "attachment; filename="+fileName)
	c.Header("Content-Type", "application/octet-stream")

	// Stream to client
	// Gin's DataFromReader is perfect for this
	// We don't know exact size easily without Stat (already called inside service),
	// Service could return info.Size but let's assume it works or use -1 if unknown
	// Actually object.Stat() is cached in minio-go object usually.
	
	stat, _ := object.Stat()
	c.DataFromReader(http.StatusOK, stat.Size, "application/octet-stream", object, map[string]string{
		"Content-Disposition": "attachment; filename="+fileName,
	})
}
