import { useCallback, useMemo } from "react"; import type { ChangeEvent } from "react"; import type { ScanTopControlsSectionProps } from "../types"; export interface ScanTopControlsModel { shouldShowGenshinSourceButton: boolean; bridgeDisabled: boolean; canStartAutoScan: boolean; canStartManualScan: boolean; canCaptureSingle: boolean; autoScanRunning: boolean; handleSourceChange: (event: ChangeEvent) => void; selectGenshinSource: () => void; openSettings: () => void; openDiagnostics: () => void; captureSingleArtifact: () => void; stopScan: () => void; runGuidedAutoScan: () => void; runAutoReviewScan: () => void; bridgeStatusText: string; bridgePillClass: string; runtimeStatusText: string; runtimePillClass: string; playerStatusText: string; autoScanButtonTitle: string; autoScanButtonLabel: string; manualScanButtonTitle: string; captureSingleButtonTitle: string; refreshCaptureSourcesTitle: string; diagnosticsButtonTitle: string; scanSetupButtonTitle: string; showPlayerProgress: boolean; progressWidth: number; progressStats: Array<{ label: string; value: number | string; extraClass?: string }>; } export function useScanTopControlsModel({ captureSources, selectedSourceId, setSelectedSourceId, captureSelectedSource, bridgeReady, isScanning, controller, }: Omit): ScanTopControlsModel { const { setSettingsOpen, setDiagnosticsOpen, requestScanStop, runGuidedAutoScan, runAutoReviewScan, autoScanRunning, canCaptureSource, canAutoScan, hasSourceSelected, requiresAdminForAutoScan, reviewStatus, runtimeInfo, autoScanStats, storedTotal, scanProgressPercent, genshinSource, } = controller; const handleSourceChange = useCallback( (event: ChangeEvent) => setSelectedSourceId(event.target.value), [setSelectedSourceId], ); const selectGenshinSource = useCallback(() => { if (genshinSource) { setSelectedSourceId(genshinSource.id); } }, [genshinSource, setSelectedSourceId]); const openSettings = useCallback(() => setSettingsOpen(true), [setSettingsOpen]); const openDiagnostics = useCallback(() => setDiagnosticsOpen(true), [setDiagnosticsOpen]); const captureSingleArtifact = useCallback(() => captureSelectedSource(0, true), [captureSelectedSource]); const stopScan = useCallback(() => requestScanStop("Stop-Button gedrueckt."), [requestScanStop]); const startGuidedAutoScan = useCallback(() => { void runGuidedAutoScan(); }, [runGuidedAutoScan]); const bridgeStatusText = bridgeReady ? "Bridge verbunden" : "Bridge fehlt"; const bridgePillClass = bridgeReady ? "elevated" : "standard"; const runtimeStatusText = runtimeInfo?.isElevated ? "Admin bereit" : "Standard"; const runtimePillClass = runtimeInfo?.isElevated ? "elevated" : "standard"; const playerStatusText = reviewStatus || (runtimeInfo?.isElevated ? "App laeuft als Administrator. Auto-Scan prueft den Screen ohne OCR und startet erst, wenn eine Artifact-Detailkarte offen ist." : "App laeuft im Standard-Modus - Auto-Scan braucht Administrator-Rechte. Bitte die App schliessen und als Administrator neu starten."); const autoScanButtonTitle = requiresAdminForAutoScan ? "App laeuft nicht als Administrator. Bitte die App als Administrator neu starten." : "Prueft zuerst ohne OCR den Screen, oeffnet bei Bedarf per Inventory-Kamera-Sequenz das Artifact-Inventar und scannt erst mit sichtbarer Detailkarte."; const autoScanButtonLabel = autoScanRunning ? "Scan laeuft..." : "Auto-Scan starten"; const manualScanButtonTitle = "Du klickst die Artifacts in Genshin selbst an; die App liest nur mit. Kein Auto-Klick, kein Scrollen."; const captureSingleButtonTitle = "Liest das gerade in Genshin geoeffnete Artifact einmalig."; const refreshCaptureSourcesTitle = "Fenster- und Bildschirmquellen neu suchen"; const diagnosticsButtonTitle = bridgeReady ? "Scanner Diagnose oeffnen: Rechte, Grid-Erkennung und Logs." : "Scanner Diagnose ist nur in der Electron-App vollstaendig nutzbar."; const scanSetupButtonTitle = bridgeReady ? "Scan-Ziel, Skip-Zeilen und Operator-Optionen anpassen." : "Scan-Setup ist nur in der Electron-App vollstaendig nutzbar."; const showPlayerProgress = autoScanRunning || autoScanStats.clicked > 0 || autoScanStats.parsed > 0; const progressStats = useMemo( () => [ { label: "Klicks", value: autoScanStats.clicked }, { label: "Positionen", value: autoScanStats.attempted }, { label: "Verifiziert", value: autoScanStats.verified }, { label: "ms/Artifact", value: autoScanStats.averageMsPerParsed || "-" }, { label: "Gespeichert", value: autoScanStats.stored }, { label: "Review", value: autoScanStats.review }, { label: "Sammlung", value: storedTotal ?? "-", extraClass: "collection" }, ], [ autoScanStats.clicked, autoScanStats.attempted, autoScanStats.verified, autoScanStats.averageMsPerParsed, autoScanStats.stored, autoScanStats.review, storedTotal, ], ); return { shouldShowGenshinSourceButton: Boolean(genshinSource && selectedSourceId !== genshinSource.id), bridgeDisabled: !bridgeReady || captureSources.length === 0, canStartAutoScan: hasSourceSelected && !isScanning && !autoScanRunning && canAutoScan && !requiresAdminForAutoScan, canStartManualScan: hasSourceSelected && !isScanning && !autoScanRunning && canCaptureSource, canCaptureSingle: hasSourceSelected && !isScanning && !autoScanRunning && canCaptureSource, autoScanRunning, handleSourceChange, selectGenshinSource, openSettings, openDiagnostics, captureSingleArtifact, stopScan, runGuidedAutoScan: startGuidedAutoScan, runAutoReviewScan, bridgeStatusText, bridgePillClass, runtimeStatusText, runtimePillClass, playerStatusText, autoScanButtonTitle, autoScanButtonLabel, manualScanButtonTitle, captureSingleButtonTitle, refreshCaptureSourcesTitle, diagnosticsButtonTitle, scanSetupButtonTitle, showPlayerProgress, progressWidth: scanProgressPercent, progressStats, }; }