package sexec

import (
	"github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/xplan"
	"github.com/tech/sendico/payments/storage/model"
	"github.com/tech/sendico/pkg/discovery"
)

type route int

const (
	routeUnknown route = iota + 1
	routeLedger
	routeCrypto
	routeProviderSettlement
	routeCardPayout
	routeObserveConfirm
	routeGuard
)

func classifyRoute(step xplan.Step) route {
	if isGuardStep(step) {
		return routeGuard
	}

	action := normalizeAction(step.Action)
	rail := normalizeRail(step.Rail)

	switch action {
	case discovery.RailOperationObserveConfirm:
		return routeObserveConfirm
	case discovery.RailOperationSend:
		switch rail {
		case discovery.RailCrypto:
			return routeCrypto
		case discovery.RailCardPayout:
			return routeCardPayout
		default:
			return routeUnknown
		}
	case discovery.RailOperationFXConvert:
		switch rail {
		case discovery.RailProviderSettlement:
			return routeProviderSettlement
		case discovery.RailLedger:
			return routeLedger
		default:
			return routeUnknown
		}
	case discovery.RailOperationFee:
		if rail == discovery.RailCrypto {
			return routeCrypto
		}
		return routeUnknown
	default:
		if isLedgerAction(action) {
			return routeLedger
		}
		return routeUnknown
	}
}

func isGuardStep(step xplan.Step) bool {
	return xplan.GuardStepKind(step) != xplan.StepKindUnspecified
}

func isLedgerAction(action model.RailOperation) bool {
	switch action {
	case discovery.RailOperationDebit,
		discovery.RailOperationCredit,
		discovery.RailOperationExternalDebit,
		discovery.RailOperationExternalCredit,
		discovery.RailOperationMove,
		discovery.RailOperationBlock,
		discovery.RailOperationRelease:
		return true
	default:
		return false
	}
}

func normalizeAction(action model.RailOperation) model.RailOperation {
	return model.ParseRailOperation(string(action))
}

func normalizeRail(rail model.Rail) model.Rail {
	return model.ParseRail(string(rail))
}
