package iace

import (
	"fmt"

	"github.com/xuri/excelize/v2"
)

// FMEAExportRow represents one row in the VDA FMEA worksheet.
type FMEAExportRow struct {
	ComponentName string `json:"component_name"`
	ComponentType string `json:"component_type"`
	FailureMode   string `json:"failure_mode"`
	FailureEffect string `json:"failure_effect"`
	FailureCause  string `json:"failure_cause"`
	Severity      int    `json:"severity"`
	Occurrence    int    `json:"occurrence"`
	Detection     int    `json:"detection"`
	RPZ           int    `json:"rpz"`
	AP            string `json:"ap"`
	Measure       string `json:"measure"`
	DetectionHint string `json:"detection_hint"`
}

// GenerateFMEAExcel creates a VDA-format FMEA worksheet as xlsx bytes.
func GenerateFMEAExcel(projectName string, rows []FMEAExportRow) ([]byte, error) {
	f := excelize.NewFile()
	sheet := "FMEA-Worksheet"
	f.SetSheetName("Sheet1", sheet)

	// Column widths
	widths := map[string]float64{
		"A": 6, "B": 25, "C": 14, "D": 28, "E": 30, "F": 28,
		"G": 6, "H": 6, "I": 6, "J": 8, "K": 6, "L": 30, "M": 25,
	}
	for col, w := range widths {
		_ = f.SetColWidth(sheet, col, col, w)
	}

	// Header style
	headerStyle, _ := f.NewStyle(&excelize.Style{
		Font:      &excelize.Font{Bold: true, Size: 10, Color: "FFFFFF"},
		Fill:      excelize.Fill{Type: "pattern", Pattern: 1, Color: []string{"4472C4"}},
		Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
		Border: []excelize.Border{
			{Type: "left", Color: "000000", Style: 1}, {Type: "right", Color: "000000", Style: 1},
			{Type: "top", Color: "000000", Style: 1}, {Type: "bottom", Color: "000000", Style: 1},
		},
	})

	// Title row
	f.SetCellValue(sheet, "A1", fmt.Sprintf("FMEA-Worksheet — %s", projectName))
	titleStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{Bold: true, Size: 14},
	})
	f.SetCellStyle(sheet, "A1", "A1", titleStyle)
	f.MergeCell(sheet, "A1", "M1")

	// Sub-header
	f.SetCellValue(sheet, "A2", "AIAG-VDA FMEA Format | AP = Action Priority (H/M/L)")
	f.MergeCell(sheet, "A2", "M2")

	// Column headers (row 4)
	headers := []string{"Nr.", "Komponente", "Typ", "Fehlerart", "Fehlerfolge", "Fehlerursache",
		"S", "O", "D", "RPZ", "AP", "Empfohlene Massnahme", "Erkennung"}
	for i, h := range headers {
		cell := fmt.Sprintf("%s4", string(rune('A'+i)))
		f.SetCellValue(sheet, cell, h)
		f.SetCellStyle(sheet, cell, cell, headerStyle)
	}

	// Data rows
	dataStyle, _ := f.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{WrapText: true, Vertical: "top"},
		Border: []excelize.Border{
			{Type: "left", Color: "D0D0D0", Style: 1}, {Type: "right", Color: "D0D0D0", Style: 1},
			{Type: "bottom", Color: "D0D0D0", Style: 1},
		},
	})
	apHigh, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{Bold: true, Color: "FFFFFF"},
		Fill: excelize.Fill{Type: "pattern", Pattern: 1, Color: []string{"FF0000"}},
		Alignment: &excelize.Alignment{Horizontal: "center"},
	})
	apMed, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{Bold: true},
		Fill: excelize.Fill{Type: "pattern", Pattern: 1, Color: []string{"FFD700"}},
		Alignment: &excelize.Alignment{Horizontal: "center"},
	})
	apLow, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{Bold: true, Color: "FFFFFF"},
		Fill: excelize.Fill{Type: "pattern", Pattern: 1, Color: []string{"00B050"}},
		Alignment: &excelize.Alignment{Horizontal: "center"},
	})

	for i, row := range rows {
		r := i + 5 // data starts at row 5
		f.SetCellValue(sheet, fmt.Sprintf("A%d", r), i+1)
		f.SetCellValue(sheet, fmt.Sprintf("B%d", r), row.ComponentName)
		f.SetCellValue(sheet, fmt.Sprintf("C%d", r), row.ComponentType)
		f.SetCellValue(sheet, fmt.Sprintf("D%d", r), row.FailureMode)
		f.SetCellValue(sheet, fmt.Sprintf("E%d", r), row.FailureEffect)
		f.SetCellValue(sheet, fmt.Sprintf("F%d", r), row.FailureCause)
		f.SetCellValue(sheet, fmt.Sprintf("G%d", r), row.Severity)
		f.SetCellValue(sheet, fmt.Sprintf("H%d", r), row.Occurrence)
		f.SetCellValue(sheet, fmt.Sprintf("I%d", r), row.Detection)
		f.SetCellValue(sheet, fmt.Sprintf("J%d", r), row.RPZ)
		f.SetCellValue(sheet, fmt.Sprintf("K%d", r), row.AP)
		f.SetCellValue(sheet, fmt.Sprintf("L%d", r), row.Measure)
		f.SetCellValue(sheet, fmt.Sprintf("M%d", r), row.DetectionHint)

		// Style data cells
		for c := 0; c < 13; c++ {
			cell := fmt.Sprintf("%s%d", string(rune('A'+c)), r)
			f.SetCellStyle(sheet, cell, cell, dataStyle)
		}
		// AP color
		apCell := fmt.Sprintf("K%d", r)
		switch row.AP {
		case "H":
			f.SetCellStyle(sheet, apCell, apCell, apHigh)
		case "M":
			f.SetCellStyle(sheet, apCell, apCell, apMed)
		case "L":
			f.SetCellStyle(sheet, apCell, apCell, apLow)
		}
	}

	buf, err := f.WriteToBuffer()
	if err != nil {
		return nil, fmt.Errorf("excel write: %w", err)
	}
	return buf.Bytes(), nil
}
