import React, { useEffect, useState, useCallback, useRef } from 'react';
import { Playlist, ServerType, SyncStrategy, PlexServerConnection, PathMappingConfig, PathMappingMode, PlexConnectionSettings, SyncState, ScheduleSettings, ScheduleMode, BackupSettings } from './types';
import { apiService } from './services/api';
import { 
  STRIPE_BASE_SPEED,
  STRIPE_DECEL_DURATION_MS,
  STRIPE_TILE_SIZE,
  STRIPE_BACKGROUND_SIZE,
  SYNC_SUCCESS_TOTAL_MS,
  SYNC_ERROR_RESET_MS,
  TOAST_AUTO_DISMISS_MS,
  TOAST_EXIT_DURATION_MS
} from './Config';
import { SYNC_BANNER_PADDING_X, SYNC_BANNER_PADDING_Y, SYNC_BANNER_MIN_WIDTH } from './Config';
import ServerPanel from './components/ServerPanel';
import StrategySelector from './components/StrategySelector';
import ConnectionModal from './components/ConnectionModal';
import OverflowMarquee from './components/OverflowMarquee';
import { ArrowLeftRight, ShieldCheck, X, Server, ServerOff, Clock, Eye, EyeOff, Type, Code2, Archive, Languages } from 'lucide-react';
import { useLanguage } from './LanguageContext';

interface Toast {
  id: number;
  message: string;
  exiting: boolean;
  entering: boolean;
}

// Custom hook to handle the stripe animation logic
const useStripeAnimation = (syncState: SyncState) => {
  const leftYellowRef = useRef<HTMLDivElement>(null);
  const leftGreenRef = useRef<HTMLDivElement>(null);
  const rightYellowRef = useRef<HTMLDivElement>(null);
  const rightGreenRef = useRef<HTMLDivElement>(null);

  const requestRef = useRef<number>();
  const lastTimeRef = useRef<number>(0);
  const offsetRef = useRef<number>(0);

  // State tracking for deceleration
  const isDeceleratingRef = useRef(false);
  const decelStartTimeRef = useRef(0);

  const animate = (time: number) => {
    if (lastTimeRef.current === 0) lastTimeRef.current = time;
    const dt = (time - lastTimeRef.current) / 1000;
    lastTimeRef.current = time;

    let speed = STRIPE_BASE_SPEED; // pixels per second

    if (isDeceleratingRef.current) {
      const t = time - decelStartTimeRef.current;
      const duration = STRIPE_DECEL_DURATION_MS; // deceleration duration
      if (t >= duration) {
        speed = 0;
      } else {
        // Linear slow down
        speed = speed * (1 - (t / duration));
      }
    }

    // Update offset
    offsetRef.current += speed * dt;
    const modOffset = offsetRef.current % STRIPE_TILE_SIZE;

    // Apply to DOM elements directly for performance
    const leftPos = `right ${modOffset}px top 0`;
    const rightPos = `left ${modOffset}px top 0`;

    if (leftYellowRef.current) leftYellowRef.current.style.backgroundPosition = leftPos;
    if (leftGreenRef.current) leftGreenRef.current.style.backgroundPosition = leftPos;
    if (rightYellowRef.current) rightYellowRef.current.style.backgroundPosition = rightPos;
    if (rightGreenRef.current) rightGreenRef.current.style.backgroundPosition = rightPos;

    // Continue loop if moving or if we are in the middle of decelerating
    if (speed > 0 || (isDeceleratingRef.current && (time - decelStartTimeRef.current) < STRIPE_DECEL_DURATION_MS)) {
      requestRef.current = requestAnimationFrame(animate);
    }
  };

  useEffect(() => {
    if (syncState === SyncState.SYNCING) {
      isDeceleratingRef.current = false;
      lastTimeRef.current = 0;
      // Start animation loop
      if (!requestRef.current) {
        requestRef.current = requestAnimationFrame(animate);
      }
    } else if (syncState === SyncState.SUCCESS) {
      isDeceleratingRef.current = true;
      decelStartTimeRef.current = performance.now();
      // Ensure loop is running to handle deceleration phase
      if (!requestRef.current) {
        requestRef.current = requestAnimationFrame(animate);
      }
    } else {
      // IDLE or ERROR: Stop animation
      if (requestRef.current) {
        cancelAnimationFrame(requestRef.current);
        requestRef.current = undefined;
      }
      offsetRef.current = 0;
    }

    return () => {
      if (requestRef.current) {
        cancelAnimationFrame(requestRef.current);
        requestRef.current = undefined;
      }
    };
  }, [syncState]);

  return { leftYellowRef, leftGreenRef, rightYellowRef, rightGreenRef };
};

const App: React.FC = () => {
  const { t, language, setLanguage } = useLanguage();
  const [localPlaylists, setLocalPlaylists] = useState<Playlist[]>([]);
  const [cloudPlaylists, setCloudPlaylists] = useState<Playlist[]>([]);
  const [cloudServerInfo, setCloudServerInfo] = useState<PlexServerConnection | undefined>(undefined);
  const [localPath, setLocalPath] = useState<string>('');
  const [connectionSettings, setConnectionSettings] = useState<PlexConnectionSettings | null>(null);

  const [loadingLocal, setLoadingLocal] = useState(false);
  const [loadingCloud, setLoadingCloud] = useState(false);

  const [syncState, setSyncState] = useState<SyncState>(SyncState.IDLE);
  const manualSyncInProgress = useRef(false);
  const lastKnownSyncTimeRef = useRef<string | null | undefined>(undefined);

  // Animation Refs
  const { leftYellowRef, leftGreenRef, rightYellowRef, rightGreenRef } = useStripeAnimation(syncState);

  // Abort Controllers for Refresh Actions
  const localAbortRef = useRef<AbortController | null>(null);
  const cloudAbortRef = useRef<AbortController | null>(null);

  // Connection Modal State
  const [isConnectionModalOpen, setIsConnectionModalOpen] = useState(false);
  const [isLangMenuOpen, setIsLangMenuOpen] = useState(false);

  // Strategy State
  const [currentStrategy, setCurrentStrategy] = useState<SyncStrategy>(SyncStrategy.LOCAL_OVERWRITE);
  
  // Path Mapping State (Includes Simple and Regex Rules)
  const [pathMappingConfig, setPathMappingConfig] = useState<PathMappingConfig>({
    mode: PathMappingMode.SIMPLE,
    simple: [],
    regex: {
      localPre: [],
      localPost: [],
      remotePre: [],
      remotePost: []
    }
  });

  // Schedule State
  const [scheduleSettings, setScheduleSettings] = useState<ScheduleSettings>({
    mode: ScheduleMode.DISABLED,
    cronExpression: '',
    dailyTime: '02:00',
    weeklyDays: [0], // Sunday
    weeklyTime: '03:00',
    autoWatch: false
  });
  const [nextRunTime, setNextRunTime] = useState<string | undefined>(undefined);

  // Backup State
  const [backupSettings, setBackupSettings] = useState<BackupSettings>({
    enabled: false,
    retentionCount: 5
  });

  // Toast Notification System
  const [toasts, setToasts] = useState<Toast[]>([]);
  const timeoutsRef = useRef<{[key: number]: ReturnType<typeof setTimeout>}>({});

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(t => t.id !== id));
    if (timeoutsRef.current[id]) {
      clearTimeout(timeoutsRef.current[id]);
      delete timeoutsRef.current[id];
    }
  };

  const addToast = useCallback((message: string) => {
    const id = Date.now();
    // Start with entering: true to position it above
    const newToast: Toast = { id, message, exiting: false, entering: true };
    
    setToasts(prev => {
      // Mark all existing toasts as exiting immediately so they slide up
      const exitingToasts = prev.map(t => ({ ...t, exiting: true, entering: false }));
      return [...exitingToasts, newToast];
    });

    // Auto dismiss the new toast after configured duration
    const dismissTimer = setTimeout(() => {
      setToasts(prev => prev.map(t => t.id === id ? { ...t, exiting: true } : t));
    }, TOAST_AUTO_DISMISS_MS);
    
    timeoutsRef.current[id] = dismissTimer;
  }, []);

  // Effect to trigger the "slide down" animation
  useEffect(() => {
    const enteringIds = toasts.filter(t => t.entering).map(t => t.id);
    
    if (enteringIds.length > 0) {
      let raf1: number;
      let raf2: number;

      raf1 = requestAnimationFrame(() => {
        raf2 = requestAnimationFrame(() => {
          setToasts(prev => prev.map(t => 
            enteringIds.includes(t.id) ? { ...t, entering: false } : t
          ));
        });
      });
      
      return () => {
        cancelAnimationFrame(raf1);
        cancelAnimationFrame(raf2);
      };
    }
  }, [toasts]);

  // Cleanup effect for exiting toasts
  useEffect(() => {
    const exitingToasts = toasts.filter(t => t.exiting);
    exitingToasts.forEach(t => {
      if (!timeoutsRef.current[`remove-${t.id}`]) {
        timeoutsRef.current[`remove-${t.id}`] = setTimeout(() => {
          removeToast(t.id);
          delete timeoutsRef.current[`remove-${t.id}`];
        }, TOAST_EXIT_DURATION_MS);
      }
    });
  }, [toasts]);

  const loadSettings = useCallback(async () => {
    const result = await apiService.getSettings();
    if (result.status === 'success') {
      setCurrentStrategy(result.data.strategy);
      setPathMappingConfig(result.data.pathMapping);
      setLocalPath(result.data.localPath || 'playlist');
      setConnectionSettings(result.data.connection);
    }
  }, []);

  const loadSchedule = useCallback(async () => {
    const result = await apiService.getScheduleSettings();
    if (result.status === 'success') {
      setScheduleSettings(result.data);
      setNextRunTime(result.data.nextRun);
    }
  }, []);

  const loadBackupSettings = useCallback(async () => {
    const result = await apiService.getBackupSettings();
    if (result.status === 'success') {
      setBackupSettings(result.data);
    }
  }, []);

  // Handle Schedule Save
  const handleSaveSchedule = async (settings: ScheduleSettings): Promise<boolean> => {
    const result = await apiService.saveScheduleSettings(settings);
    
    if (result.status === 'success') {
       setScheduleSettings(settings);
       // Refresh schedule info to get next run time
       loadSchedule();

       if (settings.mode === ScheduleMode.DISABLED) {
         addToast(t('toasts.scheduleDisabled'));
       } else if (settings.mode === ScheduleMode.CRON && settings.cronExpression.trim() === '') {
         addToast(t('toasts.scheduleEmpty'));
       } else {
         addToast(t('toasts.scheduleStarted'));
       }
       return true;
    } else {
       addToast(result.message || t('toasts.scheduleFailed'));
       return false;
    }
  };

  // Handle Backup Settings Save
  const handleSaveBackupSettings = async (settings: BackupSettings) => {
    const result = await apiService.saveBackupSettings(settings);
    if (result.status === 'success') {
      setBackupSettings(settings);
      addToast(t('toasts.backupSaved'));
    } else {
      addToast(result.message || t('toasts.backupFailed'));
    }
  };

  // Fetch Local Playlists
  const refreshLocal = useCallback(async () => {
    if (localAbortRef.current) localAbortRef.current.abort();
    const abortController = new AbortController();
    localAbortRef.current = abortController;

    setLoadingLocal(true);
    const result = await apiService.getPlaylists(ServerType.LOCAL, abortController.signal, localPath || undefined);
    if (result.status === 'success') {
      setLocalPlaylists(result.data);
    }
    setLoadingLocal(false);
    localAbortRef.current = null;
  }, [localPath]);

  const cancelLocalRefresh = () => {
    if (localAbortRef.current) {
      localAbortRef.current.abort();
      localAbortRef.current = null;
      setLoadingLocal(false);
      addToast(t('toasts.localRefreshCancelled'));
    }
  };

  // Fetch Cloud Playlists and Info
  const refreshCloud = useCallback(async () => {
    if (cloudAbortRef.current) cloudAbortRef.current.abort();
    const abortController = new AbortController();
    cloudAbortRef.current = abortController;

    setLoadingCloud(true);
    // Fetch playlists
    const playlistResult = await apiService.getPlaylists(ServerType.CLOUD, abortController.signal);
    if (!abortController.signal.aborted) {
      if (playlistResult.status === 'success') {
        setCloudPlaylists(playlistResult.data);
      }
      
      // Fetch server info
      const infoResult = await apiService.getServerStatus(abortController.signal);
      if (infoResult.status === 'success') {
        setCloudServerInfo(infoResult.data);
      }
      
      setLoadingCloud(false);
      cloudAbortRef.current = null;
    }
  }, []);

  const cancelCloudRefresh = () => {
    if (cloudAbortRef.current) {
      cloudAbortRef.current.abort();
      cloudAbortRef.current = null;
      setLoadingCloud(false);
      addToast(t('toasts.cloudRefreshCancelled'));
    }
  };

  // Load persisted configuration
  useEffect(() => {
    loadSettings();
    loadSchedule();
    loadBackupSettings();
  }, [loadSettings, loadSchedule, loadBackupSettings]);

  // Initial Load
  useEffect(() => {
    refreshLocal();
    refreshCloud();
    return () => {
      // Cleanup on unmount
      if (localAbortRef.current) localAbortRef.current.abort();
      if (cloudAbortRef.current) cloudAbortRef.current.abort();
    }
  }, [refreshLocal, refreshCloud]);

  // Handle Strategy Change
  const handleStrategyChange = async (strategy: SyncStrategy, label: string) => {
    setCurrentStrategy(strategy);
    const result = await apiService.updateSyncStrategy(strategy);
    if (result.status === 'success') {
      addToast(t('toasts.strategySaved', { strategy: label }));
    } else {
      addToast(result.message || t('toasts.strategySaveFailed'));
    }
  };

  // Handle Path Mapping Save
  const handleSavePathMapping = async (config: PathMappingConfig) => {
    setPathMappingConfig(config);
    const result = await apiService.savePathMapping(config);
    if (result.status === 'success') {
      addToast(t('toasts.mappingSaved'));
    } else {
      addToast(result.message || t('toasts.mappingSaveFailed'));
    }
  };

  // Handle Sync Trigger
  const handleSyncTrigger = async () => {
    if (syncState !== SyncState.IDLE) return;

    setSyncState(SyncState.SYNCING);
    manualSyncInProgress.current = true;

    const result = await apiService.syncPlaylists(currentStrategy, pathMappingConfig, localPath || undefined);

    manualSyncInProgress.current = false;

    if (result.status === 'success') {
      setSyncState(SyncState.SUCCESS);

      setTimeout(() => {
        setSyncState(SyncState.IDLE);
        refreshLocal();
        refreshCloud();
      }, SYNC_SUCCESS_TOTAL_MS);
    } else {
      setSyncState(SyncState.ERROR);
      addToast(result.message || t('toasts.syncFailed'));
      setTimeout(() => setSyncState(SyncState.IDLE), SYNC_ERROR_RESET_MS);
    }
  };

  // SSE for sync status
  useEffect(() => {
    const eventSource = new EventSource(`${import.meta.env.VITE_API_BASE_URL || ''}/api/sync/events`);

    eventSource.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        const { is_syncing, status, error, last_sync_time } = data;

        // Initialize lastKnownSyncTime if it's the first event
        if (lastKnownSyncTimeRef.current === undefined) {
            lastKnownSyncTimeRef.current = last_sync_time;
            // If we are currently syncing on load, show it
            if (is_syncing && !manualSyncInProgress.current) {
                setSyncState(SyncState.SYNCING);
            }
            return;
        }

        // If manual sync is in progress, we ignore background updates to avoid state conflict
        if (manualSyncInProgress.current) {
            if (last_sync_time !== lastKnownSyncTimeRef.current) {
                lastKnownSyncTimeRef.current = last_sync_time;
            }
            return;
        }

        // Handle Syncing State
        if (is_syncing) {
          if (syncState !== SyncState.SYNCING) {
            setSyncState(SyncState.SYNCING);
          }
        } else {
          // Check for completion by comparing timestamps
          if (last_sync_time !== lastKnownSyncTimeRef.current) {
             lastKnownSyncTimeRef.current = last_sync_time;
             
             // A sync has completed since our last check
             if (status === 'success') {
                setSyncState(SyncState.SUCCESS);
                refreshLocal();
                refreshCloud();
               addToast(t('toasts.backgroundSyncSuccess'));
                setTimeout(() => setSyncState(SyncState.IDLE), SYNC_SUCCESS_TOTAL_MS);
             } else if (status === 'error') {
                setSyncState(SyncState.ERROR);
               addToast(t('toasts.backgroundSyncFailed', { error: error || '' }));
                setTimeout(() => setSyncState(SyncState.IDLE), SYNC_ERROR_RESET_MS);
             }
          } else {
             // Edge case: We are in SYNCING state but backend says not syncing, and time hasn't changed.
             if (syncState === SyncState.SYNCING) {
                 setSyncState(SyncState.IDLE);
             }
          }
        }
      } catch (e) {
        console.error("Failed to parse SSE event", e);
      }
    };

    eventSource.onerror = (err) => {
        console.error("EventSource failed:", err);
        eventSource.close();
    };

    return () => {
      eventSource.close();
    };
  }, [syncState, refreshLocal, refreshCloud, addToast]);

  const handleConnectSuccess = async (serverInfo: PlexServerConnection) => {
    setCloudServerInfo(serverInfo);
    if (serverInfo.libraryName) {
      await apiService.updateLibrary(serverInfo.libraryName);
    }
    // Reload settings to ensure we have the latest connection details (protocol, etc.)
    await loadSettings();
    
    // Refresh playlists after new connection
    refreshCloud();
  };

  const getToastStyles = (toast: Toast): React.CSSProperties => {
    if (toast.exiting || toast.entering) {
      return {
        opacity: 0,
        transform: 'translateY(-40px) scale(0.95)',
      };
    }
    return {
      opacity: 1,
      transform: 'translateY(0) scale(1)',
    };
  };

  const getToastClasses = () => {
    return "absolute top-2 flex items-center space-x-2 px-4 py-2 rounded-full shadow-lg border text-sm font-medium pointer-events-auto bg-gray-800 text-plex-orange border-plex-orange/30 transition-all duration-300 ease-out origin-top z-50 backdrop-blur-md";
  };

  const isConnected = cloudServerInfo?.isConnected;

  const getScheduleDisplayInfo = () => {
    const result = {
      label: t('dashboard.autoSync'),
      value: t('schedule.notConfigured'),
      active: false,
      autoWatch: scheduleSettings.autoWatch,
    };

    if (scheduleSettings.mode === ScheduleMode.DISABLED) {
      result.value = t('common.disabled');
      return result;
    }

    if (scheduleSettings.mode === ScheduleMode.CRON && scheduleSettings.cronExpression.trim() === '') {
      result.value = t('dashboard.notSet');
    } else {
      result.value = nextRunTime ? `${nextRunTime}` : t('common.loading');
    }

    result.active = true;
    return result;
  };

  const scheduleInfo = getScheduleDisplayInfo();

  // Helper: Calculate Path Mapping Info
  const getPathMappingDisplayInfo = (config: PathMappingConfig) => {
    let count = 0;
    let Icon = Type;

    if (config.mode === PathMappingMode.SIMPLE) {
      count = config.simple.length;
      Icon = Type;
    } else {
      count =
        config.regex.localPre.length +
        config.regex.localPost.length +
        config.regex.remotePre.length +
        config.regex.remotePost.length;
      Icon = Code2;
    }

    if (count === 0) {
      return {
        label: t('dashboard.mapping'),
        value: t('dashboard.notSet'),
        active: false,
        Icon,
      };
    }

    const modeLabel = config.mode === PathMappingMode.SIMPLE ? t('mapping.simple') : t('mapping.regex');

    return {
      label: t('dashboard.mapping'),
      value: `${modeLabel} (${count})`,
      active: true,
      Icon,
    };
  };

  const pathMappingInfo = getPathMappingDisplayInfo(pathMappingConfig);

  // Helper: Calculate Backup Info
  const getBackupDisplayInfo = (settings: BackupSettings) => {
    if (!settings.enabled) {
      return {
        label: t('dashboard.backup'),
        value: t('common.disabled'),
        active: false,
      };
    }
    return {
      label: t('dashboard.backup'),
      value: t('dashboard.keep', { count: settings.retentionCount }),
      active: true,
    };
  };

  const backupInfo = getBackupDisplayInfo(backupSettings);

  return (
    <div className="min-h-screen flex flex-col bg-gray-900 text-gray-100 font-sans overflow-hidden bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-gray-800 via-gray-900 to-black">
      
      {/* App Header */}
      <header className={`flex-none shadow-md z-20 relative backdrop-blur-md transition-all duration-500 ease-in-out h-16 ${syncState === SyncState.IDLE ? 'bg-gray-800/80 border-b border-white/5' : 'bg-black border-none'}`}>

        {/* Syncing/Success Animated Background Layer */}
        {syncState !== SyncState.IDLE && (
          <div className="absolute inset-0 w-full h-full overflow-hidden bg-black">

            {/* Left Side */}
            <div className="absolute left-0 top-0 bottom-0 w-1/2 overflow-hidden z-0">
              <div
                ref={leftYellowRef}
                className={`absolute inset-0 transition-opacity duration-300 ease-out ${syncState === SyncState.SUCCESS ? 'opacity-0' : 'opacity-100'}`}
                style={{
                  backgroundPosition: 'right 0 top 0',
                  backgroundImage: `repeating-linear-gradient(135deg, transparent, transparent 20px, #e5a00d 20px, #e5a00d 40px)`,
                  backgroundSize: STRIPE_BACKGROUND_SIZE,
                }}
              />
              <div
                ref={leftGreenRef}
                className={`absolute inset-0 transition-opacity duration-300 ease-out ${syncState === SyncState.SUCCESS ? 'opacity-100' : 'opacity-0'}`}
                style={{
                  backgroundPosition: 'right 0 top 0',
                  backgroundImage: `repeating-linear-gradient(135deg, transparent, transparent 20px, #22c55e 20px, #22c55e 40px)`,
                  backgroundSize: STRIPE_BACKGROUND_SIZE,
                }}
              />
            </div>

            {/* Right Side */}
            <div className="absolute right-0 top-0 bottom-0 w-1/2 overflow-hidden z-0">
              <div
                ref={rightYellowRef}
                className={`absolute inset-0 transition-opacity duration-300 ease-out ${syncState === SyncState.SUCCESS ? 'opacity-0' : 'opacity-100'}`}
                style={{
                  backgroundPosition: 'left 0 top 0',
                  backgroundImage: `repeating-linear-gradient(225deg, transparent, transparent 20px, #e5a00d 20px, #e5a00d 40px)`,
                  backgroundSize: STRIPE_BACKGROUND_SIZE,
                }}
              />
              <div
                ref={rightGreenRef}
                className={`absolute inset-0 transition-opacity duration-300 ease-out ${syncState === SyncState.SUCCESS ? 'opacity-100' : 'opacity-0'}`}
                style={{
                  backgroundPosition: 'left 0 top 0',
                  backgroundImage: `repeating-linear-gradient(225deg, transparent, transparent 20px, #22c55e 20px, #22c55e 40px)`,
                  backgroundSize: STRIPE_BACKGROUND_SIZE,
                }}
              />
            </div>
          </div>
        )}

        {/* Content Container */}
        <div className="relative max-w-7xl mx-auto px-4 md:px-6 h-full flex items-center justify-between">

          {syncState === SyncState.IDLE ? (
            <>
              {/* Normal Toolbar Left */}
              <div className="flex items-center space-x-3">
                <div className="p-1.5 rounded-lg shadow-lg bg-gradient-to-br from-plex-orange to-yellow-600 text-gray-900 shadow-plex-orange/20">
                   <ArrowLeftRight size={24} strokeWidth={2.5} />
                </div>
                <h1 className="text-xl font-bold tracking-tight text-white">
                  Plex<span className="text-plex-orange">Sync</span>
                </h1>
              </div>
              
              {/* Normal Toolbar Right */}
              <div className="flex items-center gap-4">
                  
                  {/* Unified Status Dock */}
                  <div className="hidden md:flex items-center bg-gray-900/40 border border-gray-700/50 rounded-lg p-1 mr-2 backdrop-blur-sm shadow-sm transition-all hover:bg-gray-900/60 hover:border-gray-600/50">
                      
                      {/* Path Mapping Section */}
                      <div className="flex flex-col px-3 py-0.5 border-r border-gray-700/30 w-[120px] group/item">
                         <span className={`text-[9px] font-bold uppercase tracking-widest transition-colors ${pathMappingInfo.active ? 'text-plex-orange' : 'text-gray-500 group-hover/item:text-gray-400'}`}>{pathMappingInfo.label}</span>
                         <div className={`flex items-center gap-1.5 text-xs font-medium ${pathMappingInfo.active ? 'text-blue-400' : 'text-gray-600'}`}>
                            <pathMappingInfo.Icon size={12} strokeWidth={2.5} className="flex-shrink-0" />
                              <OverflowMarquee>
                                {pathMappingInfo.active ? pathMappingInfo.value : t('common.none')}
                              </OverflowMarquee>
                         </div>
                      </div>

                      {/* Backup Section */}
                      <div className="flex flex-col px-3 py-0.5 border-r border-gray-700/30 w-[100px] group/item">
                         <span className={`text-[9px] font-bold uppercase tracking-widest transition-colors ${backupInfo.active ? 'text-plex-orange' : 'text-gray-500 group-hover/item:text-gray-400'}`}>{backupInfo.label}</span>
                         <div className={`flex items-center gap-1.5 text-xs font-medium ${backupInfo.active ? 'text-indigo-400' : 'text-gray-600'}`}>
                            <Archive size={12} strokeWidth={2.5} className="flex-shrink-0" />
                           <OverflowMarquee>
                             {backupInfo.active ? t('dashboard.retain', { count: backupSettings.retentionCount }) : backupInfo.value}
                           </OverflowMarquee>
                         </div>
                      </div>

                      {/* Schedule Section */}
                      <div className="flex flex-col px-3 py-0.5 w-[180px] group/item">
                         <div className="flex items-center justify-between">
                            <span className={`text-[9px] font-bold uppercase tracking-widest transition-colors ${scheduleInfo.active ? 'text-plex-orange' : 'text-gray-500 group-hover/item:text-gray-400'}`}>{scheduleInfo.label}</span>
                            {/* Watch Indicator Badge */}
                            <div 
                                className={`flex items-center gap-1 px-1 rounded-[2px] transition-colors ${scheduleInfo.autoWatch ? 'text-plex-orange bg-plex-orange/10' : 'text-gray-700 bg-gray-800'}`}
                                title={scheduleInfo.autoWatch ? t('dashboard.watchModeActive') : t('dashboard.watchModeDisabled')}
                            >
                                {scheduleInfo.autoWatch ? <Eye size={9} /> : <EyeOff size={9} />}
                                <span className="text-[8px] font-bold uppercase">{t('dashboard.watch')}</span>
                            </div>
                         </div>
                         <div className={`flex items-center gap-1.5 text-xs font-medium mt-0.5 ${scheduleInfo.active ? 'text-green-400' : 'text-gray-600'}`}>
                            <Clock size={12} strokeWidth={2.5} className="flex-shrink-0" />
                           <OverflowMarquee>
                            {scheduleInfo.active ? scheduleInfo.value : t('common.disabled')}
                           </OverflowMarquee>
                         </div>
                      </div>
                  </div>

                  {/* Language Switcher */}
                  <div className="relative">
                    <button
                      onClick={() => setIsLangMenuOpen(!isLangMenuOpen)}
                      className="flex items-center justify-center w-9 h-9 rounded-full border border-gray-700 bg-gray-800/50 text-gray-400 hover:text-white hover:bg-gray-700 transition-all"
                      title={t('common.switchLanguage')}
                    >
                      <Languages size={18} />
                    </button>
                    {isLangMenuOpen && (
                      <>
                        <div className="fixed inset-0 z-40" onClick={() => setIsLangMenuOpen(false)}></div>
                        <div className="absolute right-0 top-full mt-2 w-32 bg-gray-800 border border-gray-700 rounded-lg shadow-xl z-50 overflow-hidden">
                          <button 
                            onClick={() => { setLanguage('en'); setIsLangMenuOpen(false); }}
                            className={`w-full px-4 py-2 text-sm text-left hover:bg-gray-700 transition-colors ${language === 'en' ? 'text-plex-orange font-bold' : 'text-gray-300'}`}
                          >
                            English
                          </button>
                          <button 
                            onClick={() => { setLanguage('es'); setIsLangMenuOpen(false); }}
                            className={`w-full px-4 py-2 text-sm text-left hover:bg-gray-700 transition-colors ${language === 'es' ? 'text-plex-orange font-bold' : 'text-gray-300'}`}
                          >
                            Español
                          </button>
                          <button 
                            onClick={() => { setLanguage('chs'); setIsLangMenuOpen(false); }}
                            className={`w-full px-4 py-2 text-sm text-left hover:bg-gray-700 transition-colors ${language === 'chs' ? 'text-plex-orange font-bold' : 'text-gray-300'}`}
                          >
                            简体中文
                          </button>
                        </div>
                      </>
                    )}
                  </div>

                  {/* Connection Status Button */}
                  <button 
                    onClick={() => setIsConnectionModalOpen(true)}
                    className={`flex items-center justify-center w-9 h-9 rounded-full border transition-all duration-300 hover:scale-105 active:scale-95 shadow-md 
                      ${isConnected 
                        ? "bg-green-500/10 border-green-500/50 text-green-400 hover:bg-green-500/20 hover:shadow-green-500/20"
                        : "bg-red-500/10 border-red-500/50 text-red-400 hover:bg-red-500/20 hover:shadow-red-500/20"
                      }`}
                    title={isConnected ? t('dashboard.connected') : t('dashboard.disconnected')}
                  >
                    {isConnected ? <Server size={18} /> : <ServerOff size={18} />}
                  </button>
              </div>
            </>
          ) : (
            /* Syncing / Success Text Banner */
            <div className="absolute inset-0 flex items-center justify-center pointer-events-none z-10">
               <div
                 className="bg-black shadow-none rounded-none border-none"
                 style={{
                   padding: `${SYNC_BANNER_PADDING_Y}px ${SYNC_BANNER_PADDING_X}px`,
                   minWidth: `${SYNC_BANNER_MIN_WIDTH}px`,
                 }}
               >
                  <h1 className={`text-xl md:text-2xl font-black tracking-[0.2em] uppercase whitespace-nowrap transition-colors duration-300 ${syncState === SyncState.SUCCESS ? 'text-[#22c55e]' : 'text-[#F59E0B]'}`}>
                    {syncState === SyncState.SYNCING ? t('dashboard.synchronizing') : t('dashboard.syncComplete')}
                  </h1>
               </div>
            </div>
          )}

        </div>
      </header>

      {/* Notification Toasts Container */}
      <div className="fixed top-20 left-0 right-0 flex justify-center h-0 overflow-visible z-[100] pointer-events-none">
        {toasts.map((toast) => (
          <div 
            key={toast.id}
            className={getToastClasses()}
            style={getToastStyles(toast)}
          >
              <ShieldCheck size={16} />
              <span>{toast.message}</span>
              <button 
                onClick={() => setToasts(prev => prev.map(t => t.id === toast.id ? { ...t, exiting: true } : t))}
                className="ml-2 hover:text-white transition-colors"
              >
                <X size={14} />
              </button>
          </div>
        ))}
      </div>

      {/* Main Content Area */}
      <main className="flex-1 overflow-hidden relative z-10">
        {/* Reduced gap from gap-3/gap-6 to gap-2/gap-3 for tighter layout */}
        <div className="absolute inset-0 flex flex-col md:flex-row max-w-7xl mx-auto p-4 md:p-6 gap-2 md:gap-3">
          
          {/* Left Column - Local */}
          <div className="flex-1 min-h-0 h-full w-full">
            <ServerPanel 
              type={ServerType.LOCAL}
              playlists={localPlaylists}
              isLoading={loadingLocal}
              onRefresh={refreshLocal}
              onCancel={cancelLocalRefresh}
            />
          </div>

          {/* Strategy Selector - Positioned specifically between headers */}
          <div className="absolute 
              z-30
              /* Mobile Positioning: Center Vertically, Anchored Right */
              top-1/2 right-[52px] transform translate-x-1/2 -translate-y-1/2
              
              /* Desktop Positioning: Center Horizontally, Anchored Top */
              md:top-[64px] md:right-auto md:left-1/2 md:transform md:-translate-x-1/2 md:-translate-y-1/2"
          >
              <StrategySelector 
                currentStrategy={currentStrategy}
                onSelect={handleStrategyChange}
                savedPathMapping={pathMappingConfig}
                onSavePathMapping={handleSavePathMapping}
                savedBackup={backupSettings}
                onSaveBackup={handleSaveBackupSettings}
                savedSchedule={scheduleSettings}
                onSaveSchedule={handleSaveSchedule}
                syncState={syncState}
                onSync={handleSyncTrigger}
              />
          </div>

          {/* Right Column - Cloud */}
          <div className="flex-1 min-h-0 h-full w-full">
            <ServerPanel 
              type={ServerType.CLOUD}
              playlists={cloudPlaylists}
              isLoading={loadingCloud}
              onRefresh={refreshCloud}
              onCancel={cancelCloudRefresh}
              serverInfo={cloudServerInfo}
            />
          </div>

        </div>
      </main>
      
      {/* Footer */}
      <footer className="flex-none py-4 text-center text-xs text-gray-600 border-t border-white/5 bg-gray-900/50 backdrop-blur">
        <p>{t('app.footer', { year: new Date().getFullYear() })}</p>
      </footer>

      {/* Modals */}
      <ConnectionModal
        isOpen={isConnectionModalOpen}
        onClose={() => setIsConnectionModalOpen(false)}
        onConnectSuccess={handleConnectSuccess}
        onShowMessage={addToast}
        initialSettings={connectionSettings || undefined}
      />
    </div>
  );
};

export default App;
