package errors

import (
	"fmt"
	"strings"
)

// ValidationErrorDetail хранит данные об одной ошибке.
type ValidationErrorDetail struct {
	Code      ErrorCode // Код ошибки
	Message   string    // Текст сообщения
	Line      int       // Номер строки, где возникла ошибка
	Column    int       // Позиция в строке
	EndLine   int       // Конечная строка
	EndColumn int       // Конечный столбец
}

// ValidationError представляет совокупность ошибок валидации.
type ValidationError struct {
	Errors []ValidationErrorDetail
}

// Error возвращает строковое представление всех ошибок.
func (ve *ValidationError) Error() string {
	var sb strings.Builder
	sb.WriteString("Найдены ошибки валидации:\n")
	for i, errDetail := range ve.Errors {
		sb.WriteString(fmt.Sprintf("%d) [%s] (Line %d, Col %d): %s\n", i+1, errDetail.Code, errDetail.Line, errDetail.Column, errDetail.Message))
	}
	return sb.String()
}

// AddDetail добавляет новую ошибку в список.
func (ve *ValidationError) AddDetail(code ErrorCode, message string, line, column int) {
	ve.Errors = append(ve.Errors, ValidationErrorDetail{
		Code:    code,
		Message: message,
		Line:    line,
		Column:  column,
	})
}

func (ve *ValidationError) AddDetailWithSpan(code ErrorCode, message string, line, col, endLine, endCol int) {
	ve.Errors = append(ve.Errors, ValidationErrorDetail{
		Code:      code,
		Message:   message,
		Line:      line,
		Column:    col,
		EndLine:   endLine,
		EndColumn: endCol,
	})
}

// IsEmpty проверяет, имеются ли ошибки.
func (ve *ValidationError) IsEmpty() bool {
	return len(ve.Errors) == 0
}