// Package handlers provides HTTP handlers for the rdev API.
package handlers

import (
	"fmt"

	"github.com/orchard9/rdev/internal/domain"
)

// WorkTaskDTO is the data transfer object for work tasks.
type WorkTaskDTO struct {
	ID          string         `json:"id"`
	ProjectID   string         `json:"project_id"`
	Type        string         `json:"type"`
	Spec        map[string]any `json:"spec"`
	Status      string         `json:"status"`
	Priority    int            `json:"priority"`
	WorkerID    string         `json:"worker_id,omitempty"`
	CallbackURL string         `json:"callback_url,omitempty"`
	CreatedAt   string         `json:"created_at"`
	StartedAt   string         `json:"started_at,omitempty"`
	CompletedAt string         `json:"completed_at,omitempty"`
	Result      *WorkResultDTO `json:"result,omitempty"`
	Error       string         `json:"error,omitempty"`
	RetryCount  int            `json:"retry_count"`
	MaxRetries  int            `json:"max_retries"`
}

// WorkResultDTO is the data transfer object for work results.
type WorkResultDTO struct {
	Output    string            `json:"output,omitempty"`
	Artifacts map[string]string `json:"artifacts,omitempty"`
}

// toWorkTaskDTO converts a domain.WorkTask to a WorkTaskDTO.
func toWorkTaskDTO(t *domain.WorkTask) *WorkTaskDTO {
	if t == nil {
		return nil
	}
	dto := &WorkTaskDTO{
		ID:          t.ID,
		ProjectID:   t.ProjectID,
		Type:        string(t.Type),
		Spec:        t.Spec,
		Status:      string(t.Status),
		Priority:    t.Priority,
		WorkerID:    t.WorkerID,
		CallbackURL: t.CallbackURL,
		CreatedAt:   t.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
		Error:       t.Error,
		RetryCount:  t.RetryCount,
		MaxRetries:  t.MaxRetries,
	}
	if t.StartedAt != nil {
		dto.StartedAt = t.StartedAt.Format("2006-01-02T15:04:05Z07:00")
	}
	if t.CompletedAt != nil {
		dto.CompletedAt = t.CompletedAt.Format("2006-01-02T15:04:05Z07:00")
	}
	if t.Result != nil {
		dto.Result = &WorkResultDTO{
			Output:    t.Result.Output,
			Artifacts: t.Result.Artifacts,
		}
	}
	return dto
}

// formatDuration formats a duration in a human-readable way.
func formatDuration(d interface{ Seconds() float64 }) string {
	secs := d.Seconds()
	if secs < 60 {
		return fmt.Sprintf("%.0fs", secs)
	}
	mins := secs / 60
	if mins < 60 {
		return fmt.Sprintf("%.1fm", mins)
	}
	hours := mins / 60
	if hours < 24 {
		return fmt.Sprintf("%.1fh", hours)
	}
	days := hours / 24
	return fmt.Sprintf("%.1fd", days)
}
