package entity

import "time"

// RecognitionStatus представляет статус операции распознавания у провайдера.
type RecognitionStatus int

const (
	// RecognitionStatusInProgress - операция в процессе выполнения
	RecognitionStatusInProgress RecognitionStatus = iota
	// RecognitionStatusCompleted - операция завершена успешно
	RecognitionStatusCompleted
	// RecognitionStatusFailed - операция завершена с ошибкой
	RecognitionStatusFailed
)

// String возвращает строковое представление статуса
func (s RecognitionStatus) String() string {
	switch s {
	case RecognitionStatusInProgress:
		return "in_progress"
	case RecognitionStatusCompleted:
		return "completed"
	case RecognitionStatusFailed:
		return "failed"
	default:
		return "unknown"
	}
}

// RecognitionResult представляет исход опроса операции распознавания.
type RecognitionResult struct {
	Status RecognitionStatus
	Error  string // Текст ошибки (заполняется при StatusFailed)
}

// NewInProgressResult создает результат для операции в процессе выполнения
func NewInProgressResult() *RecognitionResult {
	return &RecognitionResult{
		Status: RecognitionStatusInProgress,
	}
}

// NewCompletedResult создает результат для успешно завершенной операции
func NewCompletedResult() *RecognitionResult {
	return &RecognitionResult{
		Status: RecognitionStatusCompleted,
	}
}

// NewFailedResult создает результат для операции, завершенной с ошибкой
func NewFailedResult(errorText string) *RecognitionResult {
	return &RecognitionResult{
		Status: RecognitionStatusFailed,
		Error:  errorText,
	}
}

// IsInProgress проверяет, находится ли операция в процессе выполнения
func (r *RecognitionResult) IsInProgress() bool {
	return r.Status == RecognitionStatusInProgress
}

// IsCompleted проверяет, завершена ли операция успешно
func (r *RecognitionResult) IsCompleted() bool {
	return r.Status == RecognitionStatusCompleted
}

// IsFailed проверяет, завершена ли операция с ошибкой
func (r *RecognitionResult) IsFailed() bool {
	return r.Status == RecognitionStatusFailed
}

// GetError возвращает текст ошибки (только для операций, завершенных с ошибкой)
func (r *RecognitionResult) GetError() string {
	if r.IsFailed() {
		return r.Error
	}
	return ""
}

// Recognition — попытка распознавания у внешнего провайдера.
//
// Всё провайдерское живёт здесь, а не колонками записи: идентификатор операции —
// самое провайдерское, что есть в модели, а копия аудио во внешнем хранилище
// существует только потому, что сегодняшний провайдер читает запись по адресу.
// Другой провайдер её не потребует, и смена провайдера не трогает доменную
// сущность вовсе.
//
// Сохранённый ответ провайдера лежит **третьим файлом в подкаталоге записи**, а
// не колонкой этой строки: шаг опроса читает её раз в несколько секунд, а
// репозиторий читает строку целиком — ответ на многочасовую запись ехал бы в
// память при каждом опросе. Хранится он потому, что результат операции у
// провайдера не переспрашивается.
type Recognition struct {
	Id       string
	RecordID string
	Provider string
	Model    string
	// ExternalID — идентификатор операции у провайдера. Заводится **до**
	// обращения к нему: окно между ответом провайдера и записью идентификатора —
	// то место, где теряется оплаченное.
	ExternalID string
	// SourceURI — адрес, по которому провайдер читает аудио.
	SourceURI  string
	StartedAt  *time.Time
	FinishedAt *time.Time
}

// RecognitionOutcome — доменный результат распознавания, каким его отдаёт
// адаптер. Формата провайдера здесь нет: разбор потока — обязанность адаптера, и
// ни один шаг конвейера не знает, каким потоком и какими полями провайдер
// отвечает.
type RecognitionOutcome struct {
	// Replicas — реплики со временем от начала записи.
	Replicas []Replica
	// PlainText — плоский текст расшифровки.
	PlainText string
	// Raw — ответ провайдера целиком, как он пришёл, на хранение отдельным файлом.
	Raw []byte
}
