import { useEffect, useState } from 'react';
import { Info } from 'lucide-react';
import type { DashboardHealthQueryState } from '../api';
import { ChannelBuilderScreen } from '../builder/ChannelBuilder';
import { Card } from '../components';
import {
  parseLibrariesSubRoute,
  parseMediaSubRoute
} from '../routing';
import { ApiKeyScreen } from '../screens/ApiKeyScreen';
import { AutoTuneScreen } from '../screens/AutoTuneScreen';
import { BlockPlayoutTroubleshootingScreen } from '../screens/BlockPlayoutTroubleshootingScreen';
import { BlocksScreen } from '../screens/BlocksScreen';
import { ChannelEditScreen } from '../screens/ChannelEditScreen';
import { ChannelsScreen } from '../screens/ChannelsScreen';
import { CollectionsScreen } from '../screens/CollectionsScreen';
import { DashboardScreen } from '../screens/DashboardScreen';
import { DecoTemplatesScreen } from '../screens/DecoTemplatesScreen';
import { DecosScreen } from '../screens/DecosScreen';
import { FFmpegProfilesScreen } from '../screens/FFmpegProfilesScreen';
import { FillerPresetsScreen } from '../screens/FillerPresetsScreen';
import { GuideScreen } from '../screens/GuideScreen';
import { ImageBrowserScreen } from '../screens/ImageBrowserScreen';
import { LibrariesScreen } from '../screens/LibrariesScreen';
import { LocalLibraryEditScreen } from '../screens/LocalLibraryEditScreen';
import { LogsScreen } from '../screens/LogsScreen';
import { MediaBrowseScreen } from '../screens/MediaBrowseScreen';
import {
  ArtistDetailScreen,
  MovieDetailScreen,
  SeasonDetailScreen,
  ShowDetailScreen
} from '../screens/MediaDetailScreen';
import { MultiCollectionsScreen } from '../screens/MultiCollectionsScreen';
import { PathReplacementsEditScreen } from '../screens/PathReplacementsEditScreen';
import { PlaybackTroubleshootingScreen } from '../screens/PlaybackTroubleshootingScreen';
import { PlexSourceScreen } from '../screens/PlexSourceScreen';
import { PlaylistsScreen } from '../screens/PlaylistsScreen';
import { PlayoutsRouteScreen } from '../screens/PlayoutsScreen';
import { RemoteConnectionEditScreen } from '../screens/RemoteConnectionEditScreen';
import { RemoteLibrariesEditScreen } from '../screens/RemoteLibrariesEditScreen';
import { RemoteSourceScreen } from '../screens/RemoteSourceScreen';
import { RerunCollectionsScreen } from '../screens/RerunCollectionsScreen';
import { SchedulesScreen } from '../screens/SchedulesScreen';
import { SearchScreen } from '../screens/SearchScreen';
import { SettingsScreen } from '../screens/SettingsScreen';
import { TemplatesScreen } from '../screens/TemplatesScreen';
import { TraktListsScreen } from '../screens/TraktListsScreen';
import { TrashScreen } from '../screens/TrashScreen';
import { TroubleshootingScreen } from '../screens/TroubleshootingScreen';
import { WatermarksScreen } from '../screens/WatermarksScreen';
import { YamlValidatorScreen } from '../screens/YamlValidatorScreen';
import {
  normalizeAppPath,
  type ScreenId,
  type ScreenRoute
} from './routes';

function NotFoundScreen() {
  const pathname = normalizeAppPath(window.location.pathname);

  return (
    <div className="ctv-screen-stack">
      <Card title={<h2>Unknown app route</h2>} subtitle="This URL does not match a ChicoryTV screen.">
        <div className="ctv-placeholder-layout">
          <div className="ctv-placeholder-icon"><Info aria-hidden="true" size={20} /></div>
          <div>
            <h3>Requested path</h3>
            <p>{pathname}</p>
          </div>
        </div>
      </Card>
    </div>
  );
}

// The Media nav entry owns detail sub-pages (/app/media/{movies|shows|seasons|artists}/{id}) and the
// image folder browser (/app/media/images/browser). Like PlayoutsRouteScreen, this wrapper tracks
// pathname locally + listens for popstate, because routeFromLocation() returns the SAME 'media'
// ScreenRoute object for the base grid and every sub-path (Object.is bails App's setActiveRoute).
export function MediaRouteScreen() {
  const [pathname, setPathname] = useState(() => window.location.pathname);
  const [search, setSearch] = useState(() => window.location.search);

  useEffect(() => {
    const onPopState = () => {
      setPathname(window.location.pathname);
      setSearch(window.location.search);
    };
    window.addEventListener('popstate', onPopState);
    return () => window.removeEventListener('popstate', onPopState);
  }, []);

  const sub = parseMediaSubRoute(pathname);

  if (sub?.kind === 'movie') {
    return <MovieDetailScreen key={pathname} id={sub.id} />;
  }
  if (sub?.kind === 'show') {
    return <ShowDetailScreen key={pathname} id={sub.id} />;
  }
  if (sub?.kind === 'season') {
    return <SeasonDetailScreen key={pathname} id={sub.id} />;
  }
  if (sub?.kind === 'artist') {
    return <ArtistDetailScreen key={pathname} id={sub.id} />;
  }
  if (sub?.kind === 'images') {
    return <ImageBrowserScreen key={pathname} />;
  }

  return <MediaBrowseScreen key={search} />;
}

// The Libraries nav entry owns the media-source editor sub-paths. CRITICAL (design §D.2, finding 4):
// unlike PlayoutsRouteScreen/MediaRouteScreen this wrapper does NOT register its own `popstate`
// listener. Its editor sub-screens register a dirty guard, so App must approve the path first and
// pass it down. This wrapper never reads a raw navigation event.
export function LibrariesRouteScreen({ subPath }: { subPath: string }) {
  const sub = parseLibrariesSubRoute(subPath);

  if (sub === null) {
    return <LibrariesScreen />;
  }

  switch (sub.kind) {
    case 'local-new':
    case 'local-edit':
      return <LocalLibraryEditScreen key={subPath} />;
    case 'remote-source':
      return sub.family === 'plex'
        ? <PlexSourceScreen key={subPath} />
        : <RemoteSourceScreen key={subPath} family={sub.family} />;
    case 'remote-connection':
      return <RemoteConnectionEditScreen key={subPath} family={sub.family} />;
    case 'remote-libraries':
      return <RemoteLibrariesEditScreen key={subPath} family={sub.family} sourceId={sub.id} />;
    case 'remote-path-replacements':
      return <PathReplacementsEditScreen key={subPath} family={sub.family} sourceId={sub.id} />;
  }
}

function assertNeverScreen(screenId: never): never {
  throw new Error(`Unhandled screen route: ${String(screenId)}`);
}

export function ScreenContent({
  healthState,
  librariesSubPath,
  route
}: {
  healthState: DashboardHealthQueryState;
  librariesSubPath: string;
  route: ScreenRoute | null;
}) {
  if (route === null) {
    return <NotFoundScreen />;
  }

  const routeId: ScreenId = route.id;

  switch (routeId) {
    case 'dashboard':
      return <DashboardScreen healthState={healthState} />;
    case 'channels':
      return <ChannelsScreen />;
    case 'builder':
      return <ChannelBuilderScreen />;
    case 'autoTune':
      return <AutoTuneScreen />;
    case 'editChannel':
      return <ChannelEditScreen key={window.location.pathname} />;
    case 'guide':
      return <GuideScreen />;
    case 'schedules':
      return <SchedulesScreen />;
    case 'blocks':
      return <BlocksScreen key={window.location.pathname} />;
    case 'templates':
      return <TemplatesScreen key={window.location.pathname} />;
    case 'decos':
      return <DecosScreen key={window.location.pathname} />;
    case 'decoTemplates':
      return <DecoTemplatesScreen key={window.location.pathname} />;
    case 'playouts':
      return <PlayoutsRouteScreen />;
    case 'libraries':
      return <LibrariesRouteScreen subPath={librariesSubPath} />;
    case 'settings':
      return <SettingsScreen />;
    case 'apiKey':
      return <ApiKeyScreen />;
    case 'media':
      return <MediaRouteScreen />;
    case 'search':
      return <SearchScreen key={window.location.search} />;
    case 'trash':
      return <TrashScreen />;
    case 'collections':
      return <CollectionsScreen />;
    case 'multiCollections':
      return <MultiCollectionsScreen />;
    case 'rerunCollections':
      return <RerunCollectionsScreen />;
    case 'playlists':
      return <PlaylistsScreen />;
    case 'traktLists':
      return <TraktListsScreen key={window.location.pathname} />;
    case 'fillerPresets':
      return <FillerPresetsScreen />;
    case 'ffmpegProfiles':
      return <FFmpegProfilesScreen />;
    case 'watermarks':
      return <WatermarksScreen />;
    case 'logs':
      return <LogsScreen />;
    case 'troubleshooting':
      return <TroubleshootingScreen />;
    case 'blockPlayoutTroubleshooting':
      return <BlockPlayoutTroubleshootingScreen />;
    case 'playbackTroubleshooting':
      return <PlaybackTroubleshootingScreen key={window.location.search} />;
    case 'yamlValidator':
      return <YamlValidatorScreen />;
    default:
      return assertNeverScreen(routeId);
  }
}
