import React, { useState, useEffect } from 'react';
import { SafeAreaView, View, StatusBar, Alert, ActivityIndicator, Text } from 'react-native';
import { useCameraPermissions } from 'expo-camera';
import * as ImagePicker from 'expo-image-picker';
import * as Haptics from 'expo-haptics';

import Header from './src/components/Header';
import Viewfinder from './src/components/Viewfinder';
import TabSelector, { TabId } from './src/components/TabSelector';
import AdjustmentPanel from './src/components/AdjustmentPanel';
import CameraControls from './src/components/CameraControls';
import PreviewModal from './src/components/PreviewModal';

import { Recipe, ColorAdjustments, FrameId, GPSInfo } from './src/types';
import { getAllRecipes, saveCustomRecipe, deleteCustomRecipe } from './src/utils/storageUtils';
import { getCurrentGPS, requestLocationPermissions } from './src/utils/locationUtils';
import { processAndExportPhoto } from './src/utils/exportEngine';

// @ts-ignore
import './global.css';

export default function App() {
  const [mode, setMode] = useState<'camera' | 'library'>('camera');
  const [recipes, setRecipes] = useState<Recipe[]>([]);
  const [selectedRecipe, setSelectedRecipe] = useState<Recipe | null>(null);
  
  // Custom temporary overrides for the sliders
  const [adjustments, setAdjustments] = useState<ColorAdjustments>({
    exposure: 0,
    contrast: 0,
    saturation: 0,
    temperature: 5500,
    tint: 0,
    highlight: 0,
    shadow: 0,
    denoise: 0,
    clarity: 0,
    grain: 0,
    colorChrome: 'none',
  });

  const [selectedFrame, setSelectedFrame] = useState<FrameId>('none');
  const [useGeotag, setUseGeotag] = useState(true);
  const [gpsInfo, setGpsInfo] = useState<GPSInfo | null>(null);
  const [activeTab, setActiveTab] = useState<TabId>('recipes');
  
  const [libraryImageUri, setLibraryImageUri] = useState<string | null>(null);
  const [lastPhotoUri, setLastPhotoUri] = useState<string | null>(null);
  const [previewVisible, setPreviewVisible] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);

  // Hardware Permissions
  const [cameraPermission, requestCameraPermission] = useCameraPermissions();

  useEffect(() => {
    loadRecipes();
    loadGPS();
  }, []);

  const loadRecipes = async () => {
    const list = await getAllRecipes();
    setRecipes(list);
    if (list.length > 0) {
      applyRecipe(list[0]);
    }
  };

  const loadGPS = async () => {
    const info = await getCurrentGPS();
    if (info) {
      setGpsInfo(info);
    }
  };

  const applyRecipe = (recipe: Recipe) => {
    setSelectedRecipe(recipe);
    setAdjustments(recipe.adjustments);
    setSelectedFrame(recipe.frameId || 'none');
    setUseGeotag(recipe.useGeotag);
  };

  const handleUpdateAdjustments = (updates: Partial<ColorAdjustments>) => {
    setAdjustments((prev) => {
      const next = { ...prev, ...updates };
      if (selectedRecipe) {
        setSelectedRecipe({
          ...selectedRecipe,
          adjustments: next,
        });
      }
      return next;
    });
  };

  const handleUpdateFrame = (frameId: FrameId) => {
    setSelectedFrame(frameId);
    if (selectedRecipe) {
      setSelectedRecipe({
        ...selectedRecipe,
        frameId,
      });
    }
  };

  const handleToggleGeotag = async (enabled: boolean) => {
    setUseGeotag(enabled);
    if (selectedRecipe) {
      setSelectedRecipe({
        ...selectedRecipe,
        useGeotag: enabled,
      });
    }
    if (enabled && !gpsInfo) {
      const locationGranted = await requestLocationPermissions();
      if (locationGranted) {
        loadGPS();
      } else {
        Alert.alert('Permission Denied', 'Enable location services to use GPS Watermark.');
        setUseGeotag(false);
      }
    }
  };

  const handleSaveRecipe = async (name: string) => {
    if (!selectedRecipe) return;
    const newRecipe = await saveCustomRecipe({
      name,
      baseFilter: selectedRecipe.baseFilter,
      adjustments,
      frameId: selectedFrame,
      useGeotag,
    });
    const list = await getAllRecipes();
    setRecipes(list);
    applyRecipe(newRecipe);
    Alert.alert('Recipe Saved', `"${name}" has been created.`);
  };

  const handleDeleteRecipe = async (id: string) => {
    await deleteCustomRecipe(id);
    const list = await getAllRecipes();
    setRecipes(list);
    if (selectedRecipe?.id === id && list.length > 0) {
      applyRecipe(list[0]);
    }
  };

  const handlePickImage = async () => {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: false,
      quality: 1,
    });

    if (!result.canceled && result.assets && result.assets.length > 0) {
      setLibraryImageUri(result.assets[0].uri);
      setMode('library');
      Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
    }
  };

  const handleCapture = async () => {
    if (mode === 'camera') {
      // For simulator & simplicity, if camera view isn't fully mocked, we use a placeholder or trigger camera picture.
      // In this setup, we simulate taking a photo or request library image if running in simulator.
      // Let's create a beautiful simulation that pulls a mock asset or lets you select one if in simulator.
      Alert.alert(
        'Capture Mode',
        'Camera capture requires native device hardware. For testing on emulators, please use the LIBRARY mode to load a photo and apply filters.',
        [{ text: 'OK' }]
      );
    } else {
      // Library mode capture/export: processes selected image with recipe, overlays, text
      if (!libraryImageUri || !selectedRecipe) {
        Alert.alert('Error', 'Please select an image from the library first.');
        return;
      }

      setIsProcessing(true);
      Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);

      const exportedUri = await processAndExportPhoto(
        libraryImageUri,
        {
          ...selectedRecipe,
          adjustments,
          frameId: selectedFrame,
          useGeotag,
        },
        selectedFrame,
        useGeotag,
        gpsInfo
      );

      setIsProcessing(false);

      if (exportedUri) {
        setLastPhotoUri(exportedUri);
        setPreviewVisible(true);
        Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
      } else {
        Alert.alert('Failed', 'Error occurred while processing image.');
      }
    }
  };

  return (
    <SafeAreaView className="flex-1 bg-carbon">
      <StatusBar barStyle="light-content" backgroundColor="#08080a" />
      
      {/* Top Header */}
      <Header mode={mode} setMode={setMode} title="CamRecipe Pro" />

      {/* Main Viewfinder Frame */}
      <View className="flex-1 justify-center items-center px-4 py-2 bg-carbon">
        <Viewfinder
          mode={mode}
          recipe={
            selectedRecipe || {
              id: 'temp',
              name: 'Custom',
              baseFilter: 'none',
              adjustments,
              frameId: selectedFrame,
              useGeotag,
            }
          }
          selectedFrame={selectedFrame}
          useGeotag={useGeotag}
          gpsInfo={gpsInfo}
          libraryImageUri={libraryImageUri}
          cameraPermissionGranted={!!cameraPermission?.granted}
          onRequestCameraPermission={requestCameraPermission}
        />
      </View>

      {/* Selector Tabs */}
      <TabSelector activeTab={activeTab} setActiveTab={setActiveTab} />

      {/* Adjustments Panel */}
      <View style={{ height: 250 }} className="bg-carbon">
        <AdjustmentPanel
          activeTab={activeTab}
          recipes={recipes}
          currentRecipeId={selectedRecipe?.id || ''}
          adjustments={adjustments}
          selectedFrame={selectedFrame}
          useGeotag={useGeotag}
          onSelectRecipe={applyRecipe}
          onUpdateAdjustments={handleUpdateAdjustments}
          onUpdateFrame={handleUpdateFrame}
          onToggleGeotag={handleToggleGeotag}
          onSaveRecipe={handleSaveRecipe}
          onDeleteRecipe={handleDeleteRecipe}
        />
      </View>

      {/* Bottom Camera Buttons */}
      <CameraControls
        lastPhotoUri={lastPhotoUri}
        onCapture={handleCapture}
        onPickImage={handlePickImage}
        onOpenPreview={() => setPreviewVisible(true)}
        isLibraryMode={mode === 'library' && !libraryImageUri}
      />

      {/* Preview Modal */}
      <PreviewModal
        visible={previewVisible}
        onClose={() => setPreviewVisible(false)}
        photoUri={lastPhotoUri}
        recipeName={selectedRecipe?.name || 'Custom'}
      />

      {/* Global Processing Loader Overlay */}
      {isProcessing && (
        <View className="absolute inset-0 bg-black/75 flex items-center justify-center space-y-4">
          <ActivityIndicator size="large" color="#f59e0b" />
          <Text className="text-amber-500 font-mono text-sm tracking-widest font-bold">
            RENDERING PHOTO...
          </Text>
        </View>
      )}
    </SafeAreaView>
  );
}
