/**
 * Camera scanning screen for card recognition.
 */

import React, { useCallback, useRef, useState, useEffect } from "react";
import {
  StyleSheet,
  View,
  Text,
  Pressable,
  ActivityIndicator,
  Dimensions,
  Image,
  Alert,
} from "react-native";
import { FontAwesome } from "@expo/vector-icons";
import { useMutation, useQuery } from "convex/react";
import { api } from "../../convex/_generated/api";
import { useCameraPermission } from "@/lib/hooks/useCamera";
import { useCurrentUser } from "@/lib/hooks";
import { useHashCache } from "@/lib/context";
import { recognizeCard, configureDebug } from "@/lib/recognition";
import { loadImageAsBase64 } from "@/lib/recognition/imageLoader";
import { decodeImageBase64 } from "@/lib/recognition/skiaDecoder";
import { AdaptiveCamera, CameraHandle, isExpoGo } from "@/components/camera";

const { height: SCREEN_HEIGHT } = Dimensions.get("window");
const CARD_ASPECT_RATIO = 63 / 88; // Width / Height
const SCAN_BOX_HEIGHT = SCREEN_HEIGHT * 0.5;
const SCAN_BOX_WIDTH = SCAN_BOX_HEIGHT * CARD_ASPECT_RATIO;

interface ScanResult {
  cardId: string;
  cardName: string;
  setCode: string;
  imageUri?: string;
  confidence: number;
  distance: number;
  timestamp: number;
}

export default function ScanScreen() {
  const { hasPermission, isLoading: permLoading, requestPermission } = useCameraPermission();
  const cameraRef = useRef<CameraHandle>(null);

  // Local scan state
  const [isProcessing, setIsProcessing] = useState(false);
  const [flashEnabled, setFlashEnabled] = useState(false);
  const [isAddingToCollection, setIsAddingToCollection] = useState(false);
  const [lastScanResult, setLastScanResult] = useState<ScanResult | null>(null);
  const [scanError, setScanError] = useState<string | null>(null);
  const [debugEnabled, setDebugEnabled] = useState(false);

  // Hash cache from context
  const { cardHashes, hashesLoaded } = useHashCache();

  // Get authenticated user
  const { user, isAuthenticated } = useCurrentUser();
  const userId = user?._id ?? null;

  // Convex mutations
  const addToCollection = useMutation(api.collections.add);
  const getCardByScryfallId = useQuery(
    api.cards.getByScryfallId,
    lastScanResult ? { scryfallId: lastScanResult.cardId } : "skip"
  );

  // Toggle debug mode
  const toggleDebug = useCallback(() => {
    const newState = !debugEnabled;
    setDebugEnabled(newState);
    configureDebug({
      enabled: newState,
      albumName: "Scry Debug",
    });
    console.log("[Scry] Debug mode:", newState ? "ON" : "OFF");
  }, [debugEnabled]);

  const clearScanState = useCallback(() => {
    setLastScanResult(null);
    setScanError(null);
  }, []);

  // Auto-clear scan result after 5 seconds
  useEffect(() => {
    if (lastScanResult) {
      const timer = setTimeout(() => {
        clearScanState();
      }, 5000);
      return () => clearTimeout(timer);
    }
  }, [lastScanResult, clearScanState]);

  const handleCapture = useCallback(async () => {
    if (!cameraRef.current || isProcessing || !hashesLoaded) return;

    setIsProcessing(true);

    try {
      // Take photo using adaptive camera
      const photo = await cameraRef.current.takePhoto();

      console.log("[Scry] Photo captured:", photo.uri);

      // Load and resize image for processing
      const { base64 } = await loadImageAsBase64(
        photo.uri,
        480, // Target width for processing
        640 // Target height
      );

      if (!base64) {
        throw new Error("Failed to load image data");
      }

      // Decode to RGBA pixels using Skia
      const decoded = decodeImageBase64(base64);

      if (!decoded) {
        throw new Error("Failed to decode image pixels");
      }

      console.log("[Scry] Image decoded:", decoded.width, "x", decoded.height);
      console.log("[Scry] Matching against", cardHashes.length, "cards");

      // Run recognition
      const result = recognizeCard(
        decoded.pixels,
        decoded.width,
        decoded.height,
        cardHashes,
        {
          enableCardDetection: true,
          enableRotationMatching: true,
          minConfidence: 0.85,
          debug: debugEnabled,
        }
      );

      console.log("[Scry] Recognition result:", result);

      if (result.success && result.match) {
        // Find the card info from our hashes
        const matchedCard = cardHashes.find((c) => c.id === result.match!.cardId);

        setLastScanResult({
          cardId: result.match.cardId,
          cardName: matchedCard?.name || "Unknown Card",
          setCode: matchedCard?.setCode || "???",
          imageUri: matchedCard?.imageUri,
          confidence: result.match.confidence,
          distance: result.match.distance,
          timestamp: Date.now(),
        });
        setScanError(null);
      } else {
        setScanError(result.error || "No match found. Try adjusting lighting or angle.");
        setLastScanResult(null);
      }
    } catch (error) {
      console.error("[Scry] Capture error:", error);
      setScanError(error instanceof Error ? error.message : "Failed to capture image");
      setLastScanResult(null);
    } finally {
      setIsProcessing(false);
    }
  }, [isProcessing, hashesLoaded, cardHashes, debugEnabled]);

  const handleAddToCollection = useCallback(async () => {
    if (!lastScanResult || !userId || !getCardByScryfallId) return;

    setIsAddingToCollection(true);

    try {
      await addToCollection({
        userId: userId as any,
        cardId: getCardByScryfallId._id,
        quantity: 1,
        isFoil: false,
      });

      Alert.alert(
        "Added to Collection",
        `${lastScanResult.cardName} has been added to your collection.`,
        [{ text: "OK" }]
      );

      clearScanState();
    } catch (error) {
      console.error("[Scry] Failed to add to collection:", error);
      Alert.alert("Error", "Failed to add card to collection. Please try again.", [
        { text: "OK" },
      ]);
    } finally {
      setIsAddingToCollection(false);
    }
  }, [lastScanResult, userId, getCardByScryfallId, addToCollection, clearScanState]);

  // Loading state
  if (permLoading) {
    return (
      <View style={styles.centered}>
        <ActivityIndicator size="large" color="#007AFF" />
        <Text style={styles.loadingText}>Checking camera permission...</Text>
      </View>
    );
  }

  // Permission denied
  if (!hasPermission) {
    return (
      <View style={styles.centered}>
        <FontAwesome name="camera" size={64} color="#666" />
        <Text style={styles.permissionTitle}>Camera Access Required</Text>
        <Text style={styles.permissionText}>
          Scry needs camera access to scan your Magic cards.
        </Text>
        <Pressable style={styles.permissionButton} onPress={requestPermission}>
          <Text style={styles.permissionButtonText}>Enable Camera</Text>
        </Pressable>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      {/* Adaptive camera - uses expo-camera in Expo Go, Vision Camera in production */}
      <AdaptiveCamera ref={cameraRef} flashEnabled={flashEnabled} />

      {/* Overlay with scan box */}
      <View style={styles.overlay}>
        {/* Top dark area */}
        <View style={styles.overlayTop} />

        {/* Middle row with scan box */}
        <View style={styles.overlayMiddle}>
          <View style={styles.overlaySide} />
          <View style={styles.scanBox}>
            {/* Corner markers */}
            <View style={[styles.corner, styles.cornerTopLeft]} />
            <View style={[styles.corner, styles.cornerTopRight]} />
            <View style={[styles.corner, styles.cornerBottomLeft]} />
            <View style={[styles.corner, styles.cornerBottomRight]} />
          </View>
          <View style={styles.overlaySide} />
        </View>

        {/* Bottom dark area */}
        <View style={styles.overlayBottom} />
      </View>

      {/* Instructions */}
      <View style={styles.instructionContainer}>
        <Text style={styles.instructionText}>
          {hashesLoaded
            ? `Position card in frame • ${cardHashes.length} cards loaded`
            : "Loading card database..."}
        </Text>
        {isExpoGo && (
          <Text style={styles.devModeText}>Dev mode (expo-camera)</Text>
        )}
      </View>

      {/* Scan result overlay */}
      {lastScanResult && (
        <View style={styles.resultContainer}>
          <View style={styles.resultCard}>
            {lastScanResult.imageUri && (
              <Image
                source={{ uri: lastScanResult.imageUri }}
                style={styles.resultImage}
                resizeMode="contain"
              />
            )}
            <View style={styles.resultInfo}>
              <Text style={styles.resultName}>{lastScanResult.cardName}</Text>
              <Text style={styles.resultSet}>{lastScanResult.setCode.toUpperCase()}</Text>
              <Text style={styles.resultConfidence}>
                {Math.round(lastScanResult.confidence * 100)}% match
              </Text>
            </View>
            <Pressable
              style={[styles.addButton, !userId && styles.addButtonDisabled]}
              onPress={handleAddToCollection}
              disabled={!userId || isAddingToCollection}
            >
              {isAddingToCollection ? (
                <ActivityIndicator size="small" color="#fff" />
              ) : (
                <>
                  <FontAwesome name="plus" size={20} color="#fff" />
                  <Text style={styles.addButtonText}>Add</Text>
                </>
              )}
            </Pressable>
          </View>
        </View>
      )}

      {/* Error message */}
      {scanError && (
        <View style={styles.errorContainer}>
          <Text style={styles.errorMessage}>{scanError}</Text>
          <Pressable onPress={clearScanState}>
            <Text style={styles.errorDismiss}>Dismiss</Text>
          </Pressable>
        </View>
      )}

      {/* Controls */}
      <View style={styles.controls}>
        {/* Flash toggle */}
        <Pressable style={styles.controlButton} onPress={() => setFlashEnabled(!flashEnabled)}>
          <FontAwesome
            name="bolt"
            size={24}
            color={flashEnabled ? "#FFD700" : "#fff"}
          />
        </Pressable>

        {/* Capture button */}
        <Pressable
          style={[styles.captureButton, isProcessing && styles.captureButtonDisabled]}
          onPress={handleCapture}
          disabled={isProcessing || !hashesLoaded}
        >
          {isProcessing ? (
            <ActivityIndicator size="small" color="#007AFF" />
          ) : (
            <View style={styles.captureButtonInner} />
          )}
        </Pressable>

        {/* Debug toggle */}
        <Pressable style={styles.controlButton} onPress={toggleDebug}>
          <FontAwesome
            name="bug"
            size={24}
            color={debugEnabled ? "#FF6B6B" : "#fff"}
          />
        </Pressable>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#000",
  },
  centered: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#1a1a1a",
    padding: 20,
  },
  loadingText: {
    marginTop: 16,
    color: "#888",
    fontSize: 16,
  },
  permissionTitle: {
    marginTop: 20,
    fontSize: 24,
    fontWeight: "bold",
    color: "#fff",
  },
  permissionText: {
    marginTop: 12,
    fontSize: 16,
    color: "#888",
    textAlign: "center",
    maxWidth: 280,
  },
  permissionButton: {
    marginTop: 24,
    backgroundColor: "#007AFF",
    paddingHorizontal: 32,
    paddingVertical: 14,
    borderRadius: 12,
  },
  permissionButtonText: {
    color: "#fff",
    fontSize: 18,
    fontWeight: "600",
  },
  errorText: {
    marginTop: 16,
    fontSize: 18,
    color: "#FF6B6B",
    textAlign: "center",
  },
  overlay: {
    ...StyleSheet.absoluteFillObject,
  },
  overlayTop: {
    flex: 1,
    backgroundColor: "rgba(0,0,0,0.6)",
  },
  overlayMiddle: {
    flexDirection: "row",
    height: SCAN_BOX_HEIGHT,
  },
  overlaySide: {
    flex: 1,
    backgroundColor: "rgba(0,0,0,0.6)",
  },
  scanBox: {
    width: SCAN_BOX_WIDTH,
    height: SCAN_BOX_HEIGHT,
    borderWidth: 2,
    borderColor: "rgba(255,255,255,0.3)",
    borderRadius: 12,
  },
  overlayBottom: {
    flex: 1,
    backgroundColor: "rgba(0,0,0,0.6)",
  },
  corner: {
    position: "absolute",
    width: 24,
    height: 24,
    borderColor: "#007AFF",
  },
  cornerTopLeft: {
    top: -2,
    left: -2,
    borderTopWidth: 4,
    borderLeftWidth: 4,
    borderTopLeftRadius: 12,
  },
  cornerTopRight: {
    top: -2,
    right: -2,
    borderTopWidth: 4,
    borderRightWidth: 4,
    borderTopRightRadius: 12,
  },
  cornerBottomLeft: {
    bottom: -2,
    left: -2,
    borderBottomWidth: 4,
    borderLeftWidth: 4,
    borderBottomLeftRadius: 12,
  },
  cornerBottomRight: {
    bottom: -2,
    right: -2,
    borderBottomWidth: 4,
    borderRightWidth: 4,
    borderBottomRightRadius: 12,
  },
  instructionContainer: {
    position: "absolute",
    top: 60,
    left: 0,
    right: 0,
    alignItems: "center",
  },
  instructionText: {
    color: "#fff",
    fontSize: 14,
    backgroundColor: "rgba(0,0,0,0.5)",
    paddingHorizontal: 16,
    paddingVertical: 8,
    borderRadius: 20,
  },
  devModeText: {
    marginTop: 8,
    color: "#FFD700",
    fontSize: 12,
    backgroundColor: "rgba(0,0,0,0.5)",
    paddingHorizontal: 12,
    paddingVertical: 4,
    borderRadius: 12,
  },
  resultContainer: {
    position: "absolute",
    bottom: 140,
    left: 16,
    right: 16,
  },
  resultCard: {
    flexDirection: "row",
    backgroundColor: "rgba(0,0,0,0.9)",
    borderRadius: 12,
    padding: 12,
    alignItems: "center",
  },
  resultImage: {
    width: 50,
    height: 70,
    borderRadius: 4,
  },
  resultInfo: {
    flex: 1,
    marginLeft: 12,
  },
  resultName: {
    color: "#fff",
    fontSize: 16,
    fontWeight: "600",
  },
  resultSet: {
    color: "#888",
    fontSize: 12,
    marginTop: 2,
  },
  resultConfidence: {
    color: "#4CD964",
    fontSize: 12,
    marginTop: 4,
  },
  addButton: {
    flexDirection: "row",
    alignItems: "center",
    backgroundColor: "#4CD964",
    paddingHorizontal: 16,
    paddingVertical: 10,
    borderRadius: 8,
    gap: 6,
  },
  addButtonDisabled: {
    opacity: 0.5,
  },
  addButtonText: {
    color: "#fff",
    fontSize: 14,
    fontWeight: "600",
  },
  errorContainer: {
    position: "absolute",
    bottom: 140,
    left: 16,
    right: 16,
    backgroundColor: "rgba(255,107,107,0.95)",
    borderRadius: 12,
    padding: 16,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  errorMessage: {
    color: "#fff",
    fontSize: 14,
    flex: 1,
  },
  errorDismiss: {
    color: "#fff",
    fontSize: 14,
    fontWeight: "600",
    marginLeft: 12,
  },
  controls: {
    position: "absolute",
    bottom: 40,
    left: 0,
    right: 0,
    flexDirection: "row",
    justifyContent: "space-around",
    alignItems: "center",
    paddingHorizontal: 40,
  },
  controlButton: {
    width: 50,
    height: 50,
    justifyContent: "center",
    alignItems: "center",
  },
  captureButton: {
    width: 72,
    height: 72,
    borderRadius: 36,
    backgroundColor: "#fff",
    justifyContent: "center",
    alignItems: "center",
    borderWidth: 4,
    borderColor: "rgba(255,255,255,0.3)",
  },
  captureButtonDisabled: {
    opacity: 0.5,
  },
  captureButtonInner: {
    width: 56,
    height: 56,
    borderRadius: 28,
    backgroundColor: "#fff",
  },
});
