package controllers

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/gofiber/fiber/v2"
	"github.com/sujit-baniya/fiber-boilerplate/app"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/helpers"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
	"gorm.io/gorm"
	// Importa el repositorio
)

func CreateVcf(c *fiber.Ctx) error {
	var data services.ContactDataVcf
	if err := json.Unmarshal(c.Body(), &data); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": "Datos inválidos",
		})
	}

	// 1. Generar el Vcf
	vcfContent, err := services.GenerateVCardVcf(data)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"error": "No se pudo generar el VCF",
		})
	}

	random := helpers.RandomString(4)
	fileName := fmt.Sprintf("vcf/vcf-%s-%s.vcf", strings.ReplaceAll(data.FirstName, " ", "_"), random)
	tmpPath := fmt.Sprintf("/tmp/vcf-%s-%s.vcf", strings.ReplaceAll(data.FirstName, " ", "_"), random)

	// 2. Guardar archivo temporal
	if err := os.WriteFile(tmpPath, vcfContent, 0644); err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"error": "No se pudo guardar el VCF temporalmente",
		})
	}
	defer os.Remove(tmpPath)

	// 3. Subir a OSS
	ossProvider, err := getOSSFromBody(c)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"error": "Error de conexión con OSS",
		})
	}

	if err := ossProvider.UploadFile(fileName, tmpPath); err != nil {
		log.Printf("Error subiendo archivo a OSS: %v", err)
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"error": "Error subiendo archivo a OSS",
		})
	}

	// 4. URL del archivo
	url := ossProvider.PublicURL(fileName)

	// 5. Buscar si ya existe un registro con ese vcard_id
	var existing models.VcfVcard
	db := app.Http.Database.DB

	err = db.Where("vcard_id = ?", data.VcardID).First(&existing).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			// No existe, crear nuevo
			newVcf := models.VcfVcard{
				Vcf:       url,
				UsuarioID: data.FirstName, // Podrías usar el ID real de usuario si lo tienes
				Email:     data.Email,
				VcardID:   data.VcardID,
			}
			if err := models.CreateVcfVcard(&newVcf); err != nil {
				return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
					"error": "No se pudo crear el registro VCF",
				})
			}
		} else {
			// Error inesperado de DB
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"error": "Error buscando VCF existente",
			})
		}
	} else {
		// Si ya existe, actualizar
		existing.Vcf = url
		existing.Email = data.Email
		existing.UsuarioID = data.FirstName
		if err := models.UpdateVcfVcard(&existing); err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"error": "No se pudo actualizar el VCF existente",
			})
		}
	}

	return c.JSON(fiber.Map{
		"success": true,
		"url":     url,
	})
}
