package responses

import (
	"strings"
	"time"

	"github.com/treytartt/honeydue-api/internal/models"
)

// TaskTemplateResponse represents a task template in the API response
type TaskTemplateResponse struct {
	ID           uint                   `json:"id"`
	Title        string                 `json:"title"`
	Description  string                 `json:"description"`
	CategoryID   *uint                  `json:"category_id"`
	Category     *TaskCategoryResponse  `json:"category,omitempty"`
	FrequencyID  *uint                  `json:"frequency_id"`
	Frequency    *TaskFrequencyResponse `json:"frequency,omitempty"`
	IconIOS      string                 `json:"icon_ios"`
	IconAndroid  string                 `json:"icon_android"`
	Tags         []string               `json:"tags"`
	DisplayOrder int                    `json:"display_order"`
	IsActive     bool                   `json:"is_active"`
	CreatedAt    time.Time              `json:"created_at"`
	UpdatedAt    time.Time              `json:"updated_at"`
}

// TaskTemplateCategoryGroup represents templates grouped by category
type TaskTemplateCategoryGroup struct {
	CategoryName string                 `json:"category_name"`
	CategoryID   *uint                  `json:"category_id"`
	Templates    []TaskTemplateResponse `json:"templates"`
	Count        int                    `json:"count"`
}

// TaskTemplatesGroupedResponse represents all templates grouped by category
type TaskTemplatesGroupedResponse struct {
	Categories []TaskTemplateCategoryGroup `json:"categories"`
	TotalCount int                         `json:"total_count"`
}

// NewTaskTemplateResponse creates a TaskTemplateResponse from a model
func NewTaskTemplateResponse(t *models.TaskTemplate) TaskTemplateResponse {
	resp := TaskTemplateResponse{
		ID:           t.ID,
		Title:        t.Title,
		Description:  t.Description,
		CategoryID:   t.CategoryID,
		FrequencyID:  t.FrequencyID,
		IconIOS:      t.IconIOS,
		IconAndroid:  t.IconAndroid,
		Tags:         parseTags(t.Tags),
		DisplayOrder: t.DisplayOrder,
		IsActive:     t.IsActive,
		CreatedAt:    t.CreatedAt,
		UpdatedAt:    t.UpdatedAt,
	}

	if t.Category != nil {
		resp.Category = NewTaskCategoryResponse(t.Category)
	}
	if t.Frequency != nil {
		resp.Frequency = NewTaskFrequencyResponse(t.Frequency)
	}

	return resp
}

// NewTaskTemplateListResponse creates a list of task template responses
func NewTaskTemplateListResponse(templates []models.TaskTemplate) []TaskTemplateResponse {
	results := make([]TaskTemplateResponse, len(templates))
	for i, t := range templates {
		results[i] = NewTaskTemplateResponse(&t)
	}
	return results
}

// NewTaskTemplatesGroupedResponse creates a grouped response from templates
func NewTaskTemplatesGroupedResponse(templates []models.TaskTemplate) TaskTemplatesGroupedResponse {
	// Group by category
	categoryMap := make(map[string]*TaskTemplateCategoryGroup)
	categoryOrder := []string{} // To maintain order

	for _, t := range templates {
		categoryName := "Uncategorized"
		var categoryID *uint
		if t.Category != nil {
			categoryName = t.Category.Name
			categoryID = &t.Category.ID
		}

		if _, exists := categoryMap[categoryName]; !exists {
			categoryMap[categoryName] = &TaskTemplateCategoryGroup{
				CategoryName: categoryName,
				CategoryID:   categoryID,
				Templates:    []TaskTemplateResponse{},
			}
			categoryOrder = append(categoryOrder, categoryName)
		}

		categoryMap[categoryName].Templates = append(categoryMap[categoryName].Templates, NewTaskTemplateResponse(&t))
	}

	// Build ordered result
	categories := make([]TaskTemplateCategoryGroup, len(categoryOrder))
	totalCount := 0
	for i, name := range categoryOrder {
		group := categoryMap[name]
		group.Count = len(group.Templates)
		totalCount += group.Count
		categories[i] = *group
	}

	return TaskTemplatesGroupedResponse{
		Categories: categories,
		TotalCount: totalCount,
	}
}

// parseTags splits a comma-separated tags string into a slice
func parseTags(tags string) []string {
	if tags == "" {
		return []string{}
	}
	parts := strings.Split(tags, ",")
	result := make([]string, 0, len(parts))
	for _, p := range parts {
		trimmed := strings.TrimSpace(p)
		if trimmed != "" {
			result = append(result, trimmed)
		}
	}
	return result
}
