package manage

import (
	"context"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/store/schedule"
)

// ListSchedulesForOwnerWithFilter lists current schedule definitions only.
func (service *Service) ListSchedulesForOwnerWithFilter(ctx context.Context, ownerUserID string, workspaceID string, filter ListFilter) ([]ScheduleView, error) {
	normalizedFilter, err := normalizeTriggerListFilter(filter)
	if err != nil {
		return nil, err
	}
	if normalizedFilter.SourceKind != "" && normalizedFilter.SourceKind != SourceKindTime {
		return []ScheduleView{}, nil
	}
	owner, err := service.loadManageOwner(ctx, workspaceID, ownerUserID)
	if err != nil {
		return nil, err
	}
	definitions, err := service.scheduleStore().ListDefinitions(ctx, schedule.DefinitionListQuery{
		WorkspaceID:         strings.TrimSpace(workspaceID),
		OwnerMemberID:       strings.TrimSpace(owner.MemberID),
		TargetKind:          string(normalizedFilter.TargetKind),
		TargetRef:           normalizedFilter.TargetRef,
		Status:              normalizedFilter.Status,
		IncludeChildThreads: normalizedFilter.IncludeChildThreads,
		Limit:               normalizedFilter.Limit,
		Offset:              normalizedFilter.Offset,
	})
	if err != nil {
		return nil, err
	}
	views := make([]ScheduleView, 0, len(definitions))
	for _, definition := range definitions {
		if strings.TrimSpace(definition.SourceKind) != schedule.SourceKindTime {
			continue
		}
		view, err := service.viewFromScheduleDefinition(ctx, ownerUserID, definition, false)
		if err != nil {
			return nil, err
		}
		views = append(views, view)
	}
	return views, nil
}

func (service *Service) ValidateScheduleForOwner(ctx context.Context, ownerUserID string, workspaceID string, input UpsertInput, existingScheduleID string) (ScheduleValidateResult, error) {
	var current *TriggerView
	var existing *definitionRecord
	if strings.TrimSpace(existingScheduleID) != "" {
		owner, err := service.loadManageOwner(ctx, workspaceID, ownerUserID)
		if err != nil {
			return ScheduleValidateResult{}, err
		}
		definition, err := service.loadScheduleDefinitionForOwner(ctx, workspaceID, owner.MemberID, existingScheduleID)
		if err != nil {
			return ScheduleValidateResult{}, err
		}
		record := definitionRecordFromScheduleDefinition(ownerUserID, definition)
		existing = &record
		view, err := service.viewFromScheduleDefinition(ctx, ownerUserID, definition, true)
		if err != nil {
			return ScheduleValidateResult{}, err
		}
		current = &view
	}

	normalized, err := service.normalizeMutation(ctx, ownerUserID, workspaceID, input, existing, service.now(), false)
	if err != nil {
		return ScheduleValidateResult{}, err
	}
	proposed := triggerViewFromRecord(normalized.record, normalized.target, normalized.validation)
	proposed.NextOccurrenceAt = normalized.proposedNextAt
	if normalized.record.TimeMode == TimeModeOneShotRelative {
		proposed.ScheduledAt = nil
	}
	return ScheduleValidateResult{Current: current, Proposed: proposed, EstimatedScheduledAt: normalized.estimatedScheduledAt}, nil
}

func (service *Service) CreateScheduleForOwner(ctx context.Context, ownerUserID string, workspaceID string, input UpsertInput) (ScheduleView, error) {
	return service.createScheduleDefinitionForOwnerWithVia(ctx, ownerUserID, workspaceID, input, "schedule_api")
}

func (service *Service) GetScheduleForOwner(ctx context.Context, ownerUserID string, workspaceID string, scheduleID string) (ScheduleView, error) {
	owner, err := service.loadManageOwner(ctx, workspaceID, ownerUserID)
	if err != nil {
		return ScheduleView{}, err
	}
	definition, err := service.loadScheduleDefinitionForOwner(ctx, workspaceID, owner.MemberID, scheduleID)
	if err != nil {
		return ScheduleView{}, err
	}
	return service.viewFromScheduleDefinition(ctx, ownerUserID, definition, true)
}

func (service *Service) UpdateScheduleForOwner(ctx context.Context, ownerUserID string, workspaceID string, scheduleID string, input UpsertInput) (ScheduleView, error) {
	route := scheduleRoute{InputID: strings.TrimSpace(scheduleID), TargetID: strings.TrimSpace(scheduleID)}
	return service.updateScheduleDefinitionForOwner(ctx, ownerUserID, workspaceID, route, input)
}

func (service *Service) PauseScheduleForOwner(ctx context.Context, ownerUserID string, workspaceID string, scheduleID string) (ScheduleView, error) {
	route := scheduleRoute{InputID: strings.TrimSpace(scheduleID), TargetID: strings.TrimSpace(scheduleID)}
	return service.pauseScheduleDefinitionForOwnerWithReason(ctx, ownerUserID, workspaceID, route, "schedule_api")
}

func (service *Service) ResumeScheduleForOwner(ctx context.Context, ownerUserID string, workspaceID string, scheduleID string) (ScheduleView, error) {
	route := scheduleRoute{InputID: strings.TrimSpace(scheduleID), TargetID: strings.TrimSpace(scheduleID)}
	return service.resumeScheduleDefinitionForOwner(ctx, ownerUserID, workspaceID, route)
}

func (service *Service) DeleteScheduleForOwner(ctx context.Context, ownerUserID string, workspaceID string, scheduleID string) error {
	route := scheduleRoute{InputID: strings.TrimSpace(scheduleID), TargetID: strings.TrimSpace(scheduleID)}
	return service.deleteScheduleDefinitionForOwner(ctx, ownerUserID, workspaceID, route)
}

func (service *Service) ListAutomationRunsForScheduleOwnerPage(ctx context.Context, ownerUserID string, workspaceID string, scheduleID string, options RunListOptions) (RunPage, error) {
	options.Limit = normalizeTriggerRunListLimit(options.Limit)
	route := scheduleRoute{InputID: strings.TrimSpace(scheduleID), TargetID: strings.TrimSpace(scheduleID)}
	return service.listAutomationRunsForSchedulePage(ctx, ownerUserID, workspaceID, route, options)
}

func (service *Service) ListAutomationRunsForScheduleOwner(ctx context.Context, ownerUserID string, workspaceID string, scheduleID string, limit int) ([]AutomationRunView, error) {
	page, err := service.ListAutomationRunsForScheduleOwnerPage(ctx, ownerUserID, workspaceID, scheduleID, RunListOptions{Limit: limit})
	if err != nil {
		return nil, err
	}
	return page.Runs, nil
}
