package handlers

import (
	"strings"
	"time"

	airrescuechecklist "wucher/internal/domain/air_rescue_checklist"
	responsedto "wucher/internal/transport/http/dto/response"
	shareddto "wucher/internal/transport/http/dto/shared"
)

func airRescuerChecklistResource(header airrescuechecklist.ChecklistHeaderView, items []airrescuechecklist.ChecklistItemView) responsedto.AirRescuerChecklistResource {
	return responsedto.AirRescuerChecklistResource{
		Type: "air_rescuer_checklist",
		ID:   idString(header.ID),
		Attributes: responsedto.AirRescuerChecklistAttributes{
			Bases: shareddto.AirRescuerChecklistBaseInfo{
				ID:               idString(header.HEMSBaseID),
				BaseName:         strings.TrimSpace(header.BaseName),
				BaseAbbreviation: strings.TrimSpace(header.BaseAbbreviation),
				BaseCategory:     strings.TrimSpace(header.BaseCategory),
			},
			ScopeCode:   airrescuechecklist.AirRescuerChecklistScopeCodeEN(header.ScopeCode),
			ScopeCodeDe: airrescuechecklist.AirRescuerChecklistScopeCodeDE(header.ScopeCode),
			Title:       strings.TrimSpace(header.Title),
			Position:    header.Position,
			Items:       mapAirRescuerChecklistItemResources(items),
			CreatedBy:   uuidStringOrEmpty(header.CreatedBy),
			CreatedAt:   header.CreatedAt.UTC().Format(time.RFC3339),
			UpdatedAt:   header.UpdatedAt.UTC().Format(time.RFC3339),
		},
	}
}

func airRescuerChecklistItemResponseData(item airrescuechecklist.ChecklistItemView) responsedto.AirRescuerChecklistItemData {
	return responsedto.AirRescuerChecklistItemData{
		Type: "air_rescuer_checklist_item",
		ID:   idString(item.ID),
		Attributes: responsedto.AirRescuerChecklistItemAttributes{
			ChecklistID: idString(item.ChecklistID),
			Name:        strings.TrimSpace(item.Name),
			Position:    item.Position,
			CreatedBy:   uuidStringOrEmpty(item.CreatedBy),
			CreatedAt:   item.CreatedAt.UTC().Format(time.RFC3339),
			UpdatedAt:   item.UpdatedAt.UTC().Format(time.RFC3339),
		},
	}
}

func buildAirRescuerChecklistGroups(
	bases []airrescuechecklist.HEMSBaseView,
	headers []airrescuechecklist.ChecklistHeaderView,
	items []airrescuechecklist.ChecklistItemView,
	requestedScope string,
) []responsedto.AirRescuerChecklistBaseGroupResource {
	itemsByChecklist := make(map[string][]airrescuechecklist.ChecklistItemView, len(items))
	for i := range items {
		key := idString(items[i].ChecklistID)
		itemsByChecklist[key] = append(itemsByChecklist[key], items[i])
	}

	headersByBaseScope := make(map[string]map[string][]airrescuechecklist.ChecklistHeaderView)
	for i := range headers {
		baseKey := idString(headers[i].HEMSBaseID)
		scopeCode := strings.ToUpper(strings.TrimSpace(headers[i].ScopeCode))
		if headersByBaseScope[baseKey] == nil {
			headersByBaseScope[baseKey] = map[string][]airrescuechecklist.ChecklistHeaderView{}
		}
		headersByBaseScope[baseKey][scopeCode] = append(headersByBaseScope[baseKey][scopeCode], headers[i])
	}

	groups := make([]responsedto.AirRescuerChecklistBaseGroupResource, 0, len(bases))
	for i := range bases {
		baseID := idString(bases[i].ID)
		groups = append(groups, responsedto.AirRescuerChecklistBaseGroupResource{
			Type: "air_rescuer_checklist_group",
			ID:   "base-" + baseID,
			Attributes: responsedto.AirRescuerChecklistBaseGroupAttributes{
				Bases: shareddto.AirRescuerChecklistBaseInfo{
					ID:               baseID,
					BaseName:         strings.TrimSpace(bases[i].BaseName),
					BaseAbbreviation: strings.TrimSpace(bases[i].BaseAbbreviation),
					BaseCategory:     strings.TrimSpace(bases[i].BaseCategory),
				},
				Tabs: buildAirRescuerChecklistTabs(headersByBaseScope[baseID], itemsByChecklist, requestedScope),
			},
		})
	}

	return groups
}

func buildAirRescuerChecklistTabs(
	headersByScope map[string][]airrescuechecklist.ChecklistHeaderView,
	itemsByChecklist map[string][]airrescuechecklist.ChecklistItemView,
	requestedScope string,
) []responsedto.AirRescuerChecklistTabResource {
	normalizedScope := strings.ToUpper(strings.TrimSpace(requestedScope))
	if normalizedScope == airrescuechecklist.AirRescuerChecklistScopeCAT {
		return []responsedto.AirRescuerChecklistTabResource{
			buildAirRescuerChecklistCATTab(headersByScope),
		}
	}
	if airrescuechecklist.IsAirRescuerChecklistPersistedScope(normalizedScope) {
		return []responsedto.AirRescuerChecklistTabResource{
			buildAirRescuerChecklistDetailTab(headersByScope, itemsByChecklist, normalizedScope),
		}
	}

	scopeOrder := airrescuechecklist.AirRescuerChecklistPersistedScopeOrder()
	tabs := make([]responsedto.AirRescuerChecklistTabResource, 0, 1+len(scopeOrder))
	tabs = append(tabs, buildAirRescuerChecklistCATTab(headersByScope))
	for i := range scopeOrder {
		tabs = append(tabs, buildAirRescuerChecklistDetailTab(headersByScope, itemsByChecklist, scopeOrder[i]))
	}
	return tabs
}

func buildAirRescuerChecklistCATTab(
	headersByScope map[string][]airrescuechecklist.ChecklistHeaderView,
) responsedto.AirRescuerChecklistTabResource {
	scopeOrder := airrescuechecklist.AirRescuerChecklistPersistedScopeOrder()
	groups := make([]responsedto.AirRescuerChecklistCATGroup, 0, len(scopeOrder))
	for i := range scopeOrder {
		scopeCode := scopeOrder[i]
		headers := headersByScope[scopeCode]
		if len(headers) == 0 {
			continue
		}
		checklists := make([]responsedto.AirRescuerChecklistCATChecklistSummary, 0, len(headers))
		for j := range headers {
			checklists = append(checklists, responsedto.AirRescuerChecklistCATChecklistSummary{
				ID:        idString(headers[j].ID),
				Title:     strings.TrimSpace(headers[j].Title),
				Position:  headers[j].Position,
				CreatedBy: uuidStringOrEmpty(headers[j].CreatedBy),
				CreatedAt: headers[j].CreatedAt.UTC().Format(time.RFC3339),
				UpdatedAt: headers[j].UpdatedAt.UTC().Format(time.RFC3339),
			})
		}
		groups = append(groups, responsedto.AirRescuerChecklistCATGroup{
			ScopeCode:       airrescuechecklist.AirRescuerChecklistScopeCodeEN(scopeCode),
			ScopeCodeDe:     airrescuechecklist.AirRescuerChecklistScopeCodeDE(scopeCode),
			ScopeCodeName:   airrescuechecklist.AirRescuerChecklistScopeDisplayName(scopeCode),
			ScopeCodeNameDe: airrescuechecklist.AirRescuerChecklistScopeDisplayNameDE(scopeCode),
			Checklists:      checklists,
		})
	}
	return responsedto.AirRescuerChecklistTabResource{
		ScopeCode:       airrescuechecklist.AirRescuerChecklistScopeCodeEN(airrescuechecklist.AirRescuerChecklistScopeCAT),
		ScopeCodeDe:     airrescuechecklist.AirRescuerChecklistScopeCodeDE(airrescuechecklist.AirRescuerChecklistScopeCAT),
		ScopeCodeName:   airrescuechecklist.AirRescuerChecklistScopeDisplayName(airrescuechecklist.AirRescuerChecklistScopeCAT),
		ScopeCodeNameDe: airrescuechecklist.AirRescuerChecklistScopeDisplayNameDE(airrescuechecklist.AirRescuerChecklistScopeCAT),
		Groups:          groups,
	}
}

func buildAirRescuerChecklistDetailTab(
	headersByScope map[string][]airrescuechecklist.ChecklistHeaderView,
	itemsByChecklist map[string][]airrescuechecklist.ChecklistItemView,
	scopeCode string,
) responsedto.AirRescuerChecklistTabResource {
	headers := headersByScope[scopeCode]
	checklists := make([]responsedto.AirRescuerChecklistTabChecklistDetail, 0, len(headers))
	for i := range headers {
		key := idString(headers[i].ID)
		checklists = append(checklists, responsedto.AirRescuerChecklistTabChecklistDetail{
			ID:             idString(headers[i].ID),
			Title:          strings.TrimSpace(headers[i].Title),
			Position:       headers[i].Position,
			ChecklistItems: mapAirRescuerChecklistItemResources(itemsByChecklist[key]),
			CreatedBy:      uuidStringOrEmpty(headers[i].CreatedBy),
			CreatedAt:      headers[i].CreatedAt.UTC().Format(time.RFC3339),
			UpdatedAt:      headers[i].UpdatedAt.UTC().Format(time.RFC3339),
		})
	}
	return responsedto.AirRescuerChecklistTabResource{
		ScopeCode:       airrescuechecklist.AirRescuerChecklistScopeCodeEN(scopeCode),
		ScopeCodeDe:     airrescuechecklist.AirRescuerChecklistScopeCodeDE(scopeCode),
		ScopeCodeName:   airrescuechecklist.AirRescuerChecklistScopeDisplayName(scopeCode),
		ScopeCodeNameDe: airrescuechecklist.AirRescuerChecklistScopeDisplayNameDE(scopeCode),
		Checklists:      &checklists,
	}
}

func mapAirRescuerChecklistItemResources(items []airrescuechecklist.ChecklistItemView) []responsedto.AirRescuerChecklistItemResource {
	out := make([]responsedto.AirRescuerChecklistItemResource, 0, len(items))
	for i := range items {
		out = append(out, responsedto.AirRescuerChecklistItemResource{
			ID:        idString(items[i].ID),
			Name:      strings.TrimSpace(items[i].Name),
			Position:  items[i].Position,
			CreatedBy: uuidStringOrEmpty(items[i].CreatedBy),
			CreatedAt: items[i].CreatedAt.UTC().Format(time.RFC3339),
			UpdatedAt: items[i].UpdatedAt.UTC().Format(time.RFC3339),
		})
	}
	return out
}

func paginateAirRescuerChecklistGroups(
	groups []responsedto.AirRescuerChecklistBaseGroupResource,
	start,
	length int,
) ([]responsedto.AirRescuerChecklistBaseGroupResource, int) {
	total := len(groups)
	if start > total {
		start = total
	}
	end := start + length
	if end > total {
		end = total
	}
	return groups[start:end], total
}
