package inspur

import (
	"encoding/csv"
	"strings"
	"time"

	"git.mchus.pro/mchus/logpile/internal/models"
	"git.mchus.pro/mchus/logpile/internal/parser"
)

// ParseSELList parses selelist.csv file with SEL events
// Format: ID, Date (MM/DD/YYYY), Time (HH:MM:SS), Sensor, Event, Status
// Example: 1,04/18/2025,09:31:18,Event Logging Disabled SEL_Status,Log area reset/cleared,Asserted
func ParseSELList(content []byte) []models.Event {
	return ParseSELListWithLocation(content, parser.DefaultArchiveLocation())
}

// ParseSELListWithLocation parses selelist.csv using provided source timezone
// for timestamps that don't contain an explicit offset.
func ParseSELListWithLocation(content []byte, location *time.Location) []models.Event {
	var events []models.Event

	text := string(content)
	lines := strings.Split(text, "\n")

	// Skip header line(s) if present
	startIdx := 0
	for i, line := range lines {
		if strings.Contains(strings.ToLower(line), "sel elist") {
			startIdx = i + 1
			break
		}
	}

	// Parse CSV data
	for i := startIdx; i < len(lines); i++ {
		line := strings.TrimSpace(lines[i])
		if line == "" {
			continue
		}

		// Parse CSV line
		r := csv.NewReader(strings.NewReader(line))
		records, err := r.Read()
		if err != nil || len(records) < 6 {
			continue
		}

		eventID := strings.TrimSpace(records[0])
		dateStr := strings.TrimSpace(records[1])
		timeStr := strings.TrimSpace(records[2])
		sensorStr := strings.TrimSpace(records[3])
		eventDesc := strings.TrimSpace(records[4])
		status := strings.TrimSpace(records[5])

		// Parse timestamp: MM/DD/YYYY HH:MM:SS
		timestamp := parseSELTimestamp(dateStr, timeStr, location)

		// Extract sensor type and name
		sensorType, sensorName := parseSensorInfo(sensorStr)

		// Determine severity
		severity := determineSELSeverity(sensorStr, eventDesc, status)

		// Build full description
		description := buildSELDescription(eventDesc, status)

		events = append(events, models.Event{
			ID:          eventID,
			Timestamp:   timestamp,
			Source:      "SEL",
			SensorType:  sensorType,
			SensorName:  sensorName,
			EventType:   eventDesc,
			Severity:    severity,
			Description: description,
			RawData:     line,
		})
	}

	return events
}

// parseSELTimestamp parses MM/DD/YYYY and HH:MM:SS into time.Time
func parseSELTimestamp(dateStr, timeStr string, location *time.Location) time.Time {
	// Combine date and time: MM/DD/YYYY HH:MM:SS
	timestampStr := dateStr + " " + timeStr

	if location == nil {
		location = parser.DefaultArchiveLocation()
	}

	// Try parsing with MM/DD/YYYY format
	t, err := time.ParseInLocation("01/02/2006 15:04:05", timestampStr, location)
	if err != nil {
		// Fallback to current time
		return time.Now()
	}

	return t
}

// parseSensorInfo extracts sensor type and name from sensor string
// Example: "Event Logging Disabled SEL_Status" -> ("sel", "SEL_Status")
// Example: "Power Supply PSU0_Status" -> ("power_supply", "PSU0_Status")
func parseSensorInfo(sensorStr string) (sensorType, sensorName string) {
	parts := strings.Fields(sensorStr)
	if len(parts) == 0 {
		return "unknown", sensorStr
	}

	// Last part is usually the sensor name
	sensorName = parts[len(parts)-1]

	// First parts form the sensor type
	if len(parts) > 1 {
		sensorType = strings.ToLower(strings.Join(parts[:len(parts)-1], "_"))
	} else {
		sensorType = "system"
	}

	return
}

// determineSELSeverity determines event severity based on sensor and event description
func determineSELSeverity(sensorStr, eventDesc, status string) models.Severity {
	lowerSensor := strings.ToLower(sensorStr)
	lowerEvent := strings.ToLower(eventDesc)
	lowerStatus := strings.ToLower(status)

	// Critical indicators
	criticalKeywords := []string{
		"critical", "failure", "fault", "error",
		"ac lost", "predictive failure", "redundancy lost",
		"going high", "going low", "transition to critical",
	}

	for _, keyword := range criticalKeywords {
		if strings.Contains(lowerSensor, keyword) ||
			strings.Contains(lowerEvent, keyword) ||
			strings.Contains(lowerStatus, keyword) {
			return models.SeverityCritical
		}
	}

	// Warning indicators
	warningKeywords := []string{
		"warning", "disabled", "non-recoverable",
		"device removed", "device absent",
	}

	for _, keyword := range warningKeywords {
		if strings.Contains(lowerSensor, keyword) ||
			strings.Contains(lowerEvent, keyword) ||
			strings.Contains(lowerStatus, keyword) {
			return models.SeverityWarning
		}
	}

	// Info indicators (normal operations)
	infoKeywords := []string{
		"presence detected", "device present", "asserted",
		"initiated by", "state asserted", "s0/g0: working",
		"power button pressed",
	}

	for _, keyword := range infoKeywords {
		if strings.Contains(lowerEvent, keyword) ||
			strings.Contains(lowerStatus, keyword) {
			return models.SeverityInfo
		}
	}

	// Default to info
	return models.SeverityInfo
}

// buildSELDescription builds human-readable description
func buildSELDescription(eventDesc, status string) string {
	if status == "Asserted" || status == "Deasserted" {
		return eventDesc
	}
	return eventDesc + " (" + status + ")"
}
