import { useCallback, useMemo, useRef, useState } from "react";
import { requiresAdminForAutomation } from "../../../lib/automationPlanner";
import {
  countScannerLearningRules,
  type ScannerLearningRules,
} from "../../../lib/scannerLearning";
import { type ParsedArtifactCandidate } from "../../../lib/artifactOcrParser";
import { analyzeReviewSamples } from "../../../lib/reviewSampleAnalysis";
import {
  parseLearnedArtifact as parseLearnedArtifactHelper,
} from "./scanViewReviewHelpers";
import { useScanRuntimeInfo } from "./useScanRuntimeInfo";
import { useScanSnapshotPublisher } from "./useScanSnapshotPublisher";
import { useScanViewActions } from "./useScanViewActions";
import { useScanViewStateSync } from "./useScanViewStateSync";
import { emptyAutoScanStats, resolveScanTargetCount, type AutoScanStats, type ScanSummary } from "../../../lib/scannerSession";
import type { ScanViewProps, ScanViewControllerResult } from "../types";
import type { CaptureResult, ClickResult, ReviewSampleRecord } from "../../../types/global";
import { createRendererRepositories } from "../../../infrastructure/repositories/rendererBridgeRepositories";

export function useScanViewController({
  snapshot,
  isScanning,
  captureSources,
  selectedSourceId,
  latestCapture,
  captureStatus,
  captureSelectedSource,
  bridgeReady,
  onStoredArtifactsChanged,
}: ScanViewProps): ScanViewControllerResult {
  const repositories = useMemo(() => createRendererRepositories(), []);
  const artifactRepo = repositories?.artifacts;
  const runtimeRepo = repositories?.runtime;
  const reviewSamplesRepo = repositories?.reviewSamples;
  const learningRepo = repositories?.learning;
  const snapshotRepo = repositories?.snapshot;
  const automationRepo = repositories?.automation;
  const captureRepo = repositories?.capture;

  const [detailsOpen, setDetailsOpen] = useState(false);
  const [diagnosticsOpen, setDiagnosticsOpen] = useState(false);
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [reviewQueueOpen, setReviewQueueOpen] = useState(false);
  const [reviewSamples, setReviewSamples] = useState<ReviewSampleRecord[]>([]);
  const [reviewSampleTotal, setReviewSampleTotal] = useState(0);
  const [reviewStatus, setReviewStatus] = useState("");
  const [autoScanRunning, setAutoScanRunning] = useState(false);
  const stopVisibleScanRef = useRef(false);
  const [autoScanStats, setAutoScanStats] = useState<AutoScanStats>(emptyAutoScanStats);
  const [scanSummary, setScanSummary] = useState<ScanSummary | null>(null);
  const [scanLimit, setScanLimit] = useState(16);
  const [scanLimitTouched, setScanLimitTouched] = useState(false);
  const [skipRows, setSkipRows] = useState(0);
  const [automationLog, setAutomationLog] = useState<string[]>([]);
  const [storedTotal, setStoredTotal] = useState<number | null>(null);
  const [devMode, setDevMode] = useState(() => localStorage.getItem("gaa-dev-mode") === "1");
  const [scannerLearningRules, setScannerLearningRules] = useState<ScannerLearningRules>({ textReplacements: {} });
  const [learningRulesLoaded, setLearningRulesLoaded] = useState(false);
  const runtimeInfo = useScanRuntimeInfo(runtimeRepo);

  const parsedArtifact = useMemo(
    () => parseLearnedArtifactHelper(latestCapture, scannerLearningRules),
    [latestCapture, scannerLearningRules],
  );

  const selectedSource = captureSources.find((source) => source.id === selectedSourceId);
  const genshinSource = captureSources.find((source) => source.isGenshinCandidate);
  const requiresAdminForAutoScan = requiresAdminForAutomation(runtimeInfo);
  const hasSourceSelected = selectedSourceId.length > 0;
  const canCaptureSource = bridgeReady && Boolean(captureRepo?.captureSource);
  const canReadReviewQueue = bridgeReady && Boolean(reviewSamplesRepo?.loadSamples);
  const canSaveReviewSample = bridgeReady && Boolean(reviewSamplesRepo?.saveSample);
  const canAutoScan = bridgeReady && Boolean(automationRepo?.clickScreen) && Boolean(automationRepo?.scrollScreen);
  const reviewAnalysis = useMemo(() => analyzeReviewSamples(reviewSamples), [reviewSamples]);
  const learningRuleCount = countScannerLearningRules(scannerLearningRules);
  const detectedInventoryCount = latestCapture?.inventoryCount?.current ?? 0;
  const activeTargetCount = autoScanRunning
    ? resolveScanTargetCount(scanLimit, detectedInventoryCount)
    : scanSummary?.targetCount ?? resolveScanTargetCount(scanLimit, detectedInventoryCount);
  const scanProgressBase = Math.max(autoScanStats.attempted, autoScanStats.parsed, autoScanStats.verified);
  const scanProgressPercent = Math.min(100, Math.round((scanProgressBase / Math.max(1, activeTargetCount)) * 100));
  const scannerModeLabel = autoScanRunning ? "Scan laeuft" : runtimeInfo?.isElevated ? "Admin bereit" : "Bereit";
  const sourceLabel = selectedSource?.name ?? "Keine Quelle";
  const gridLabel = latestCapture?.inventoryGrid ? `${latestCapture.inventoryGrid.cols} x ${latestCapture.inventoryGrid.rows}` : "warte auf Capture";
  const inventoryLabel = latestCapture?.inventoryCount?.current ? `${latestCapture.inventoryCount.current}/${latestCapture.inventoryCount.total || "?"}` : "nicht erkannt";

  const appendAutomationLog = useCallback((line: string) => {
    setAutomationLog((previous) => [...previous.slice(-11), `${new Date().toLocaleTimeString()} ${line}`]);
  }, []);

  const appendClickDiagnostics = useCallback((result: ClickResult, prefix = "input") => {
    const cursor = `${result.cursorX ?? "?"},${result.cursorY ?? "?"}`;
    const focus = result.focused ? `fg:${result.foregroundProcess || "Genshin"}` : `fg-miss:${result.foregroundProcess || "?"}`;
    const blocked = result.inputBlocked ? " input:blocked" : "";
    appendAutomationLog(`${prefix}: ${focus}${blocked} cursor ${cursor} moved:${result.moved ? "yes" : "no"} clicked:${result.clicked ? "yes" : "no"}`);
  }, [appendAutomationLog]);

  const toggleDevMode = useCallback(() => {
    setDevMode((previous) => {
      const next = !previous;
      localStorage.setItem("gaa-dev-mode", next ? "1" : "0");
      return next;
    });
  }, []);

  const parseArtifact = useCallback(
    (capture: CaptureResult | null) => parseLearnedArtifactHelper(capture, scannerLearningRules),
    [scannerLearningRules],
  );

  const {
    requestScanStop,
    saveReviewSample: handleSaveReviewSample,
    loadReviewQueue: loadReviewQueueAction,
    openReviewQueue: openReviewQueueModal,
    runAutoReviewScan,
    runVisibleGridScan,
  } = useScanViewActions({
    autoScanRunning,
    setAutoScanRunning,
    isScanning,
    stopVisibleScanRef,
    selectedSourceId,
    bridgeReady,
    automationRepo,
    runtimeInfo,
    runtimeRepo,
    scanLimit,
    skipRows,
    detectedInventoryCount,
    setScanSummary,
    setAutoScanStats,
    setReviewStatus,
    appendAutomationLog,
    appendClickDiagnostics,
    parseArtifact,
    artifactRepo,
    reviewSamplesRepo,
    learningRepo,
    onStoredArtifactsChanged,
    setReviewSampleTotal,
    setReviewSamples,
    setLearningRulesLoaded,
    setScannerLearningRules,
    setStoredTotal,
    scannerLearningRules,
    captureSelectedSource,
    latestCapture,
    parsedArtifact,
    canCaptureSource,
    setReviewQueueOpen,
  });

  useScanViewStateSync({
    artifactRepo,
    latestCapture,
    scanLimitTouched,
    setScanLimit,
    setStoredTotal,
  });

  useScanSnapshotPublisher({
    autoScanRunning,
    reviewStatus,
    captureStatus,
    selectedSourceName: selectedSource?.name ?? null,
    autoScanStats,
    scanSummary,
    snapshot,
    latestInventoryGrid: latestCapture?.inventoryGrid ?? null,
    automationLog,
    runtimeInfo,
    storedTotal,
    learningRuleCount,
    snapshotRepo,
  });

  return {
    detailsOpen,
    diagnosticsOpen,
    settingsOpen,
    reviewQueueOpen,
    reviewSamples,
    reviewSampleTotal,
    reviewStatus,
    autoScanRunning,
    autoScanStats,
    scanSummary,
    scanLimit,
    scanLimitTouched,
    skipRows,
    automationLog,
    storedTotal,
    devMode,
    scannerLearningRules,
    learningRulesLoaded,
    runtimeInfo,
    parsedArtifact,
    reviewAnalysis,
    learningRuleCount,
    detectedInventoryCount,
    scanProgressPercent,
    activeTargetCount,
    requiresAdminForAutoScan,
    hasSourceSelected,
    canCaptureSource,
    canReadReviewQueue,
    canSaveReviewSample,
    canAutoScan,
    scannerModeLabel,
    sourceLabel,
    gridLabel,
    inventoryLabel,
    selectedSource,
    genshinSource,
    setDetailsOpen,
    setDiagnosticsOpen,
    setSettingsOpen,
    setReviewQueueOpen,
    setScanSummary,
    setScanLimit,
    setScanLimitTouched,
    setSkipRows,
    toggleDevMode,
    requestScanStop,
    saveReviewSample: handleSaveReviewSample,
    loadReviewQueue: loadReviewQueueAction,
    openReviewQueue: openReviewQueueModal,
    runAutoReviewScan,
    runVisibleGridScan,
  };
}
