package models

import (
	"github.com/sujit-baniya/fiber-boilerplate/app"
	"gorm.io/gorm"
)

// ─── ProyectoTicket ───────────────────────────────────────────────────────────

type ProyectoTicket struct {
	gorm.Model
	ProyectoID   *uint           `json:"proyecto_id"   gorm:"column:proyecto_id;index"`
	PortalUserID *uint           `json:"portal_user_id" gorm:"column:portal_user_id;index"`
	AutorNombre  string          `json:"autor_nombre"  gorm:"column:autor_nombre"`
	EmailFrom    string          `json:"email_from"    gorm:"column:email_from;size:255"`
	Titulo       string          `json:"titulo"        gorm:"column:titulo"`
	Descripcion  string          `json:"descripcion"   gorm:"column:descripcion;type:text"`
	Estado       string          `json:"estado"        gorm:"column:estado;default:'abierto'"` // abierto|en_progreso|resuelto|cerrado
	Prioridad    string          `json:"prioridad"     gorm:"column:prioridad;default:'media'"` // baja|media|alta|urgente
	Origen       string          `json:"origen"        gorm:"column:origen;default:'portal'"`   // portal|email
	AsignadoA    *uint           `json:"asignado_a"    gorm:"column:asignado_a;index"`
	Asignado     *Users          `json:"asignado"      gorm:"foreignKey:AsignadoA"`
	Mensajes     []TicketMensaje `json:"mensajes"      gorm:"foreignKey:TicketID"`
}

func (ProyectoTicket) TableName() string { return "proyecto_tickets" }

// ─── TicketMensaje ────────────────────────────────────────────────────────────

type TicketMensaje struct {
	gorm.Model
	TicketID     uint   `json:"ticket_id"     gorm:"column:ticket_id;index"`
	Contenido    string `json:"contenido"     gorm:"column:contenido;type:text"`
	EsAdmin      bool   `json:"es_admin"      gorm:"column:es_admin;default:false"`
	AutorNombre  string `json:"autor_nombre"  gorm:"column:autor_nombre"`
	LeidoPortal  bool   `json:"leido_portal"  gorm:"column:leido_portal;default:false"`
}

func (TicketMensaje) TableName() string { return "ticket_mensajes" }

// ─── CRUD ─────────────────────────────────────────────────────────────────────

func GetTicketsByProyecto(proyectoID uint) ([]ProyectoTicket, error) {
	var items []ProyectoTicket
	err := app.Http.Database.DB.Where("proyecto_id = ?", proyectoID).
		Preload("Mensajes").Preload("Asignado").Order("created_at DESC").Find(&items).Error
	return items, err
}

func GetTicketByID(id uint) (*ProyectoTicket, error) {
	var item ProyectoTicket
	err := app.Http.Database.DB.Preload("Mensajes").Preload("Asignado").First(&item, id).Error
	return &item, err
}

func CreateProyectoTicket(t *ProyectoTicket) error {
	return app.Http.Database.DB.Create(t).Error
}

func UpdateTicketEstado(id uint, estado string) error {
	return app.Http.Database.DB.Model(&ProyectoTicket{}).Where("id = ?", id).
		Update("estado", estado).Error
}

func CreateTicketMensaje(m *TicketMensaje) error {
	return app.Http.Database.DB.Create(m).Error
}

func GetTicketsByPortalUser(portalUserID uint) ([]ProyectoTicket, error) {
	var items []ProyectoTicket
	err := app.Http.Database.DB.Where("portal_user_id = ?", portalUserID).
		Preload("Mensajes").Preload("Asignado").Order("created_at DESC").Find(&items).Error
	return items, err
}

func GetAllTickets(estado string) ([]ProyectoTicket, error) {
	var items []ProyectoTicket
	db := app.Http.Database.DB.Preload("Mensajes").Preload("Asignado").Order("created_at DESC")
	if estado != "" && estado != "todos" {
		db = db.Where("estado = ?", estado)
	}
	err := db.Find(&items).Error
	return items, err
}

func AssignedToUser(userID uint) error {
	return app.Http.Database.DB.Model(&ProyectoTicket{}).
		Where("asignado_a IS NULL OR asignado_a = 0").
		Update("asignado_a", userID).Error
}

func CountTicketsByEstado() map[string]int64 {
	result := map[string]int64{}
	type row struct{ Estado string; Count int64 }
	var rows []row
	app.Http.Database.DB.Model(&ProyectoTicket{}).
		Select("estado, count(*) as count").
		Group("estado").Find(&rows)
	for _, r := range rows {
		result[r.Estado] = r.Count
	}
	return result
}

// MarkTicketMessagesReadByPortal marca como leídos todos los mensajes de admin
// de un ticket para el portal user (cuando abre el ticket).
func MarkTicketMessagesReadByPortal(ticketID uint) error {
	return app.Http.Database.DB.Model(&TicketMensaje{}).
		Where("ticket_id = ? AND es_admin = true AND leido_portal = false", ticketID).
		Update("leido_portal", true).Error
}
