import React, { useEffect, useMemo, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useSetAtom } from 'jotai';
import { Icons } from 'folds';
import { useSpace } from '../../../hooks/useSpace';
import { PageNav, PageNavContent } from '../../../components/page';
import { StreamHeader } from '../../../components/stream-header';
import { useMobilePagerPane } from '../../../components/mobile-tabs-pager/MobilePagerPaneContext';
import { StreamHeaderPrimaryAction } from '../../../state/mobilePagerHeader';
import { useOpenCreateRoomModal } from '../../../state/hooks/createRoomModal';
import { useOpenCreateSpaceModal } from '../../../state/hooks/createSpaceModal';
import { activeChannelsSpaceAtom } from '../../../state/activeChannelsSpace';
import { CreateRoomType } from '../../../components/create-room/types';
import { ChannelsList } from './ChannelsList';
import { ChannelsLanding } from './ChannelsLanding';
import { ChannelsWorkspaceHorseshoe } from './ChannelsWorkspaceHorseshoe';
import { WorkspaceFooter } from './WorkspaceFooter';

// Index route at /channels/ (no space selected). Renders the shared
// StreamHeader (segment switcher) plus the resolve-active-space-or-
// show-empty-state body — same pattern as Direct's nav owning its own
// empty state. Keeping the landing inside the nav avoids rendering it
// as a sibling pane: on mobile both would collide into one screen, and
// on desktop the redirect logic would fire twice if mounted twice.
//
// `<ChannelsLanding />` is mounted **directly** as the curtain's flex
// child (NOT wrapped in `PageNavContent`). `NavEmptyCenter` relies on
// `flexGrow:1 + justifyContent:Center` for vertical centering — the
// curtain stage is `display:flex; flex-direction:column`, so direct
// mount gives the empty state the height it needs to center. Wrapping
// it in `PageNavContent` (block layout inside Scroll) would collapse
// the centering to top-aligned. Same idiom as `Direct.tsx::DirectEmpty`.
export function ChannelsRootNav() {
  const { t } = useTranslation();
  const scrollRef = useRef<HTMLDivElement>(null);
  const openCreateSpaceModal = useOpenCreateSpaceModal();
  // Skip PageNav surface in pager mode so the pager's static header
  // tabs (sitting behind the swipe strip in DOM order) show through
  // until covered by the rising curtain. See Direct.tsx for the same
  // pattern and `mobile-tabs-pager/style.css.ts::pagerStaticHeader`
  // for the full overlay contract.
  const inPagerMode = useMobilePagerPane() !== null;
  // Landing has no active workspace yet, so the Plus slot launches
  // workspace creation — mirrors the landing's own CTA, just promoted
  // into the tabs row so the action is reachable without scrolling
  // and matches the workspace-selected variant's «one Plus on the tab»
  // contract.
  const primaryAction = useMemo<StreamHeaderPrimaryAction>(
    () => ({
      iconSrc: Icons.Plus,
      label: t('Channels.workspace_switcher_create_space'),
      onClick: () => openCreateSpaceModal(),
    }),
    [t, openCreateSpaceModal]
  );
  return (
    <PageNav resizable surface={inPagerMode ? undefined : 'surfaceVariant'}>
      {/* Shared `pinKey` with the workspace-listing `Channels` below
          so pin/unpin persists when the user toggles between the
          landing CTA and a chosen workspace within the Channels tab. */}
      <StreamHeader scrollRef={scrollRef} pinKey="channels" primaryAction={primaryAction}>
        <ChannelsLanding />
      </StreamHeader>
    </PageNav>
  );
}

// Channels left pane (Mattermost-style). Segment switcher at the top,
// joined-rooms hierarchy in the middle, workspace identity plate at
// the bottom. M6 will turn the footer into a dropdown for users with
// 2+ orphan spaces; in M1 it is read-only.
//
// Note: deliberately do NOT call `useNavToActivePathMapper` here. That
// atom is owned by the legacy /<space>/ tree (Space.tsx) so the
// global rail's «click avatar → resume your last in-space path» stays
// well-defined. Channels has its own segment-level navigation.
export function Channels() {
  const { t } = useTranslation();
  const space = useSpace();
  const scrollRef = useRef<HTMLDivElement>(null);
  const inPagerMode = useMobilePagerPane() !== null;
  const openCreateRoomModal = useOpenCreateRoomModal();
  const setActiveSpace = useSetAtom(activeChannelsSpaceAtom);

  // Persist URL-driven active space so cold-starts at /channels/ resume on
  // the same workspace. `useActiveSpace` (in ChannelsLanding and
  // MobileTabsPager) subscribes to the same atom, so this write
  // immediately invalidates their cached reads — without that, the pager
  // would serve a stale `destinationFor('channels')` after a switcher
  // pick + tab swap on native.
  useEffect(() => {
    setActiveSpace(space.roomId);
  }, [setActiveSpace, space.roomId]);

  // Plus on the tabs row creates a channel inside the active workspace.
  // Single entry point for «create» on the Channels tab.
  const primaryAction = useMemo<StreamHeaderPrimaryAction>(
    () => ({
      iconSrc: Icons.Plus,
      label: t('Channels.create_channel'),
      onClick: () => openCreateRoomModal(space.roomId, CreateRoomType.TextRoom),
    }),
    [t, openCreateRoomModal, space.roomId]
  );

  return (
    <PageNav resizable surface={inPagerMode ? undefined : 'surfaceVariant'}>
      <ChannelsWorkspaceHorseshoe space={space}>
        <StreamHeader
          scrollRef={scrollRef}
          pinKey="channels"
          primaryAction={primaryAction}
          bottomPinned={<WorkspaceFooter space={space} />}
        >
          <PageNavContent scrollRef={scrollRef}>
            <ChannelsList scrollRef={scrollRef} />
          </PageNavContent>
        </StreamHeader>
      </ChannelsWorkspaceHorseshoe>
    </PageNav>
  );
}
