package models

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

// ─── Estructuras de la API pública de Atlassian Statuspage ────────────────────

type StatuspageStatus struct {
	Indicator   string `json:"indicator"`   // none, minor, major, critical
	Description string `json:"description"` // "All Systems Operational", etc.
}

type StatuspagePage struct {
	ID                string    `json:"id"`
	Name              string    `json:"name"`
	URL               string    `json:"url"`
	TimeZone          string    `json:"time_zone"`
	UpdatedAt         time.Time `json:"updated_at"`
}

type StatuspageComponent struct {
	ID                 string    `json:"id"`
	Name               string    `json:"name"`
	Status             string    `json:"status"` // operational, degraded_performance, partial_outage, major_outage, under_maintenance
	CreatedAt          time.Time `json:"created_at"`
	UpdatedAt          time.Time `json:"updated_at"`
	Position           int       `json:"position"`
	Description        string    `json:"description"`
	Showcase           bool      `json:"showcase"`
	GroupID            *string   `json:"group_id"`
	PageID             string    `json:"page_id"`
	Group              bool      `json:"group"`
	OnlyShowIfDegraded bool      `json:"only_show_if_degraded"`
}

type StatuspageIncidentUpdate struct {
	ID         string    `json:"id"`
	Status     string    `json:"status"`
	Body       string    `json:"body"`
	CreatedAt  time.Time `json:"created_at"`
	UpdatedAt  time.Time `json:"updated_at"`
}

type StatuspageIncident struct {
	ID                string                     `json:"id"`
	Name              string                     `json:"name"`
	Status            string                     `json:"status"` // investigating, identified, monitoring, resolved, postmortem
	Impact            string                     `json:"impact"` // none, minor, major, critical
	PageID            string                     `json:"page_id"`
	CreatedAt         time.Time                  `json:"created_at"`
	UpdatedAt         time.Time                  `json:"updated_at"`
	MonitoringAt      *time.Time                 `json:"monitoring_at"`
	ResolvedAt        *time.Time                 `json:"resolved_at"`
	ShortLink         string                     `json:"shortlink"`
	IncidentUpdates   []StatuspageIncidentUpdate `json:"incident_updates"`
	AffectedComponents []StatuspageComponent     `json:"components"`
}

type StatuspageScheduledMaintenance struct {
	ID                string                     `json:"id"`
	Name              string                     `json:"name"`
	Status            string                     `json:"status"` // scheduled, in_progress, verifying, completed
	Impact            string                     `json:"impact"`
	PageID            string                     `json:"page_id"`
	CreatedAt         time.Time                  `json:"created_at"`
	UpdatedAt         time.Time                  `json:"updated_at"`
	ScheduledFor      time.Time                  `json:"scheduled_for"`
	ScheduledUntil    time.Time                  `json:"scheduled_until"`
	ShortLink         string                     `json:"shortlink"`
	IncidentUpdates   []StatuspageIncidentUpdate `json:"incident_updates"`
	AffectedComponents []StatuspageComponent     `json:"components"`
}

// StatuspageSummary es la respuesta completa del endpoint /api/v2/summary.json
type StatuspageSummary struct {
	Page                   StatuspagePage                   `json:"page"`
	Status                 StatuspageStatus                 `json:"status"`
	Components             []StatuspageComponent            `json:"components"`
	Incidents              []StatuspageIncident             `json:"incidents"`
	ScheduledMaintenances  []StatuspageScheduledMaintenance `json:"scheduled_maintenances"`
}

// FetchStatuspageSummary consulta la API pública de Atlassian Statuspage.
// pageID es el identificador de tu página (ej. "yh6f0r4529hb").
func FetchStatuspageSummary(pageID string) (*StatuspageSummary, error) {
	if pageID == "" {
		return nil, fmt.Errorf("statuspage: pageID vacío")
	}
	url := fmt.Sprintf("https://%s.statuspage.io/api/v2/summary.json", pageID)

	client := &http.Client{Timeout: 8 * time.Second}
	resp, err := client.Get(url) // #nosec G107 — URL construida desde config, no desde input de usuario
	if err != nil {
		return nil, fmt.Errorf("statuspage: error de red: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("statuspage: respuesta HTTP %d", resp.StatusCode)
	}

	body, err := io.ReadAll(io.LimitReader(resp.Body, 512*1024)) // límite 512 KB
	if err != nil {
		return nil, fmt.Errorf("statuspage: error leyendo body: %w", err)
	}

	var summary StatuspageSummary
	if err := json.Unmarshal(body, &summary); err != nil {
		return nil, fmt.Errorf("statuspage: error parseando JSON: %w", err)
	}
	return &summary, nil
}

// ComponentStatusLabel devuelve una etiqueta legible en español.
func ComponentStatusLabel(status string) string {
	switch status {
	case "operational":
		return "Operacional"
	case "degraded_performance":
		return "Rendimiento degradado"
	case "partial_outage":
		return "Interrupción parcial"
	case "major_outage":
		return "Interrupción mayor"
	case "under_maintenance":
		return "En mantenimiento"
	default:
		return status
	}
}

// IndicatorColor devuelve la clase de color Tailwind para el indicador global.
func IndicatorColor(indicator string) string {
	switch indicator {
	case "none":
		return "green"
	case "minor":
		return "yellow"
	case "major":
		return "orange"
	case "critical":
		return "red"
	default:
		return "gray"
	}
}
