import 'package:flutter/material.dart'; import '../../../core/theme/app_theme.dart'; /// Mirrors `FinlyticCore.Dtos.Trading.OutcomeReason` (`TradeEnums.cs`), which the /// `/api/v1/admin/evaluations` endpoint serializes as a `JsonStringEnumConverter` /// string using the exact C# member name (e.g. `"Approved"`, `"BelowScoreThreshold"`). /// /// [unknown] is the fallback both for the server's own `Unknown = 0` default (an /// honest "we don't know" rather than a fabricated reason, Rules.md §4) and for any /// future server-side member this client doesn't recognize yet. enum OutcomeReason { unknown, approved, belowScoreThreshold, earningsLockout, simulationVeto, aiRejected, noTechnicalSetups, duplicateActiveProposal, dividendGate; static OutcomeReason fromJson(String? raw) { switch (raw) { case 'Approved': return OutcomeReason.approved; case 'BelowScoreThreshold': return OutcomeReason.belowScoreThreshold; case 'EarningsLockout': return OutcomeReason.earningsLockout; case 'SimulationVeto': return OutcomeReason.simulationVeto; case 'AiRejected': return OutcomeReason.aiRejected; case 'NoTechnicalSetups': return OutcomeReason.noTechnicalSetups; case 'DuplicateActiveProposal': return OutcomeReason.duplicateActiveProposal; case 'DividendGate': return OutcomeReason.dividendGate; case 'Unknown': default: return OutcomeReason.unknown; } } /// Exact server-side enum member name. `[FromQuery] OutcomeReason?` on /// `AdminEvaluationHistoryController` model-binds a bare enum member name from /// the query string (ASP.NET Core's default `Enum.TryParse`-based binder), not a /// JSON string — so this is what must be sent back as the `outcome` filter value. String toApiValue() { switch (this) { case OutcomeReason.approved: return 'Approved'; case OutcomeReason.belowScoreThreshold: return 'BelowScoreThreshold'; case OutcomeReason.earningsLockout: return 'EarningsLockout'; case OutcomeReason.simulationVeto: return 'SimulationVeto'; case OutcomeReason.aiRejected: return 'AiRejected'; case OutcomeReason.noTechnicalSetups: return 'NoTechnicalSetups'; case OutcomeReason.duplicateActiveProposal: return 'DuplicateActiveProposal'; case OutcomeReason.dividendGate: return 'DividendGate'; case OutcomeReason.unknown: return 'Unknown'; } } String get label { switch (this) { case OutcomeReason.approved: return 'Freigegeben'; case OutcomeReason.belowScoreThreshold: return 'Score zu niedrig'; case OutcomeReason.earningsLockout: return 'Earnings-Sperre'; case OutcomeReason.simulationVeto: return 'Simulation-Veto'; case OutcomeReason.aiRejected: return 'KI abgelehnt'; case OutcomeReason.noTechnicalSetups: return 'Kein Setup'; case OutcomeReason.duplicateActiveProposal: return 'Bereits aktiver Vorschlag'; case OutcomeReason.dividendGate: return 'Dividend-Sperre'; case OutcomeReason.unknown: return 'Unbekannt'; } } /// Color-coding for the history-list badge, reusing only colors already /// established elsewhere in the app (`AppTheme.primaryEmerald`/`accentRed` plus /// the `Colors.amber`/`Colors.purpleAccent` already used by /// `EvaluationScoreBreakdownSheet`) rather than introducing a new palette. Color get color { switch (this) { case OutcomeReason.approved: return AppTheme.primaryEmerald; case OutcomeReason.aiRejected: case OutcomeReason.simulationVeto: return AppTheme.accentRed; case OutcomeReason.belowScoreThreshold: case OutcomeReason.earningsLockout: case OutcomeReason.duplicateActiveProposal: case OutcomeReason.dividendGate: return Colors.amber; case OutcomeReason.noTechnicalSetups: case OutcomeReason.unknown: return AppTheme.textMuted; } } } /// Mirrors `FinlyticCore.Dtos.Trading.TriggerSource`. enum TriggerSource { unknown, automatic, manual; static TriggerSource fromJson(String? raw) { switch (raw) { case 'Automatic': return TriggerSource.automatic; case 'Manual': return TriggerSource.manual; case 'Unknown': default: return TriggerSource.unknown; } } String toApiValue() { switch (this) { case TriggerSource.automatic: return 'Automatic'; case TriggerSource.manual: return 'Manual'; case TriggerSource.unknown: return 'Unknown'; } } String get label { switch (this) { case TriggerSource.automatic: return 'Automatisch'; case TriggerSource.manual: return 'Manuell'; case TriggerSource.unknown: return 'Unbekannt'; } } Color get color { switch (this) { case TriggerSource.automatic: return AppTheme.accentCyan; case TriggerSource.manual: return Colors.purpleAccent; case TriggerSource.unknown: return AppTheme.textMuted; } } } /// Mirrors `FinlyticCore.Dtos.TechnicalAnalysis.UniverseSource` - which recurring /// FinlyticTechnicals selection mechanism added the ISIN to the continuously /// scanned universe before this evaluation ran. `null` on the Dart side (not /// modeled as its own enum value here) means the evaluation happened outside /// that universe entirely (e.g. a manual "Analyze now" call). enum UniverseSource { sentimentSpike, userFavorite, discovery; static UniverseSource? fromJson(String? raw) { switch (raw) { case 'SentimentSpike': return UniverseSource.sentimentSpike; case 'UserFavorite': return UniverseSource.userFavorite; case 'Discovery': return UniverseSource.discovery; default: return null; } } String get label { switch (this) { case UniverseSource.sentimentSpike: return 'Sentiment-Spike'; case UniverseSource.userFavorite: return 'Nutzer-Favorit'; case UniverseSource.discovery: return 'Discovery-Liste'; } } }