import { useCallback, useEffect, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { CircleCheckBig, CircleDot, FolderIcon } from 'lucide-react';
import type { Particle } from '@/api/types';
import { parseParticlePath, type ParticlePath } from '@/lib/particle-path';
import { useAuthStore } from '@/stores/auth-store';
import { useContainerChildren } from '@/hooks/use-container-children';
import { useListKeyboardNav } from '@/hooks/use-list-keyboard-nav';
import {
  useCreateParticle,
  useCreateStreamParticle,
} from '@/hooks/use-create-particle';
import { ParticleChildrenList } from '@/features/particles/particle-children-list';
import { ComposeOverlay } from '@/features/compose/compose-overlay';
import { ComposeQuotaIndicator } from '@/features/compose/compose-quota-indicator';
import { ConfigureContainerStep } from '@/features/compose/configure-container-step';
import { useComposeIntentStore } from '@/stores/compose-intent-store';
import { VideoAudioToggle } from '@/components/video-audio-toggle';
import { KeyHint } from '@/components/key-hint';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';

type ContainerKind = 'stream' | 'folder';

interface ContainerViewProps {
  /** Path of the container; network root when it has no segments. */
  path: ParticlePath;
  /** Present when the container is a folder particle (drives the header). */
  folderParticle?: Particle & { type: 'folder' };
}

/**
 * Browsable view of a container's children — used for both the network root
 * and folders, which share the same structure: a mixed-type child list, the
 * compose overlay, and one keyboard grammar. The root is just a folder
 * without a doc.
 */
export function ContainerView({ path, folderParticle }: ContainerViewProps) {
  const { networkId, segments } = parseParticlePath(path);
  const isRoot = segments.length === 0;
  const navigate = useNavigate();
  const userId = useAuthStore((s) => s.user?.id);

  const [composeActive, setComposeActive] = useState(false);
  const [creating, setCreating] = useState<ContainerKind | null>(null);

  const [searchParams, setSearchParams] = useSearchParams();
  const statusTab: 'open' | 'closed' =
    searchParams.get('status') === 'closed' ? 'closed' : 'open';
  const setStatusTab = (next: 'open' | 'closed') => {
    setSearchParams(
      (prev) => {
        const params = new URLSearchParams(prev);
        params.set('status', next);
        return params;
      },
      { replace: true },
    );
  };

  // Folders are shelved for now: the root lists streams only, split by
  // open/closed status (server-side filter, like before folders). Folder
  // containers keep the mixed-type child list so the recursive container
  // model can be revived later.
  const { items, isLoading, canLoadMore, loadMore } = useContainerChildren(
    path,
    { streamStatus: isRoot ? statusTab : undefined },
  );

  const createParticle = useCreateParticle();
  const createStream = useCreateStreamParticle();

  const handleOpen = useCallback(
    (particleId: string) => {
      navigate(`/${networkId}/${[...segments, particleId].join('/')}`);
    },
    [navigate, networkId, segments],
  );

  const { selectedIndex } = useListKeyboardNav({
    items,
    enabled: !composeActive && creating === null,
    onOpen: handleOpen,
  });

  // N creates a stream inside a folder. Root stream creation goes through the
  // compose flow.
  useEffect(() => {
    if (isRoot || composeActive || creating !== null) return;
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.defaultPrevented) return;
      const target = e.target as HTMLElement;
      if (
        target.tagName === 'INPUT' ||
        target.tagName === 'TEXTAREA' ||
        target.isContentEditable
      ) {
        return;
      }
      if (e.key === 'n' || e.key === 'N') {
        e.preventDefault();
        setCreating('stream');
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isRoot, composeActive, creating]);

  const handleCreateContainer = useCallback(
    async (name: string, visibleTo: string[]) => {
      if (!userId || !creating) return;
      const kind = creating;
      setCreating(null);
      const id =
        kind === 'folder'
          ? await createParticle.mutateAsync({
              path,
              type: 'folder',
              properties: { name },
              createdByHumanId: userId,
              visibleTo,
            })
          : await createStream.mutateAsync({
              networkId,
              parentPath: path,
              properties: { name },
              createdByHumanId: userId,
              visibleTo,
            });
      handleOpen(id);
    },
    [
      userId,
      creating,
      path,
      networkId,
      createParticle,
      createStream,
      handleOpen,
    ],
  );

  return (
    <div className="relative flex min-h-0 flex-1 flex-col">
      {isRoot && (
        <div className="flex shrink-0 items-center border-b p-1">
          <Tabs
            value={statusTab}
            onValueChange={(v) =>
              setStatusTab(v === 'closed' ? 'closed' : 'open')
            }
          >
            <TabsList>
              <TabsTrigger value="open">
                <CircleDot className="size-3 text-green-500" /> Open
              </TabsTrigger>
              <TabsTrigger value="closed">
                <CircleCheckBig className="size-3" /> Closed
              </TabsTrigger>
            </TabsList>
          </Tabs>
        </div>
      )}
      {folderParticle && (
        <div className="flex shrink-0 items-center gap-2 border-b px-4 py-3">
          <span className="flex size-7 items-center justify-center rounded-md bg-amber-500/15">
            <FolderIcon className="size-4 text-amber-500" />
          </span>
          <h1 className="truncate text-sm font-semibold">
            {folderParticle.properties.name}
          </h1>
        </div>
      )}

      <div className="min-h-0 flex-1 overflow-y-auto overscroll-contain pb-14 py-2">
        <ParticleChildrenList
          items={items}
          networkId={networkId}
          isLoading={isLoading}
          onOpen={handleOpen}
          selectedIndex={selectedIndex}
          canLoadMore={canLoadMore}
          onLoadMore={loadMore}
          emptyMessage={
            !isRoot
              ? 'This folder is empty. Add something using the keyboard shortcuts below.'
              : statusTab === 'closed'
                ? 'No closed streams.'
                : 'No streams here. Start a conversation using the keyboard shortcuts below.'
          }
        />
      </div>

      <ComposeOverlay
        networkId={networkId}
        targetPath={isRoot ? undefined : path}
        onActiveChange={setComposeActive}
      />
      {!composeActive && (
        <div className="pointer-events-none absolute inset-x-0 bottom-16 z-20 flex justify-center px-3">
          <ComposeQuotaIndicator networkId={networkId} />
        </div>
      )}
      <div className="pointer-events-none absolute inset-x-0 bottom-0 z-20 flex justify-center p-3">
        <div className="pointer-events-auto">
          <ContainerControls
            isRoot={isRoot}
            onCreateStream={() => setCreating('stream')}
          />
        </div>
      </div>

      {creating && (
        <ConfigureContainerStep
          kind={creating}
          networkId={networkId}
          onCancel={() => setCreating(null)}
          onSubmit={handleCreateContainer}
        />
      )}
    </div>
  );
}

function ContainerControls({
  isRoot,
  onCreateStream,
}: {
  isRoot: boolean;
  onCreateStream: () => void;
}) {
  const requestIntent = useComposeIntentStore((s) => s.request);
  return (
    <div className="flex items-center gap-4 text-sm text-white/50">
      <KeyHint keys={['↑↓', 'Enter']}>navigate</KeyHint>
      <KeyHint keys="1–9">jump</KeyHint>
      <VideoAudioToggle />
      <KeyHint
        keys="Hold `"
        onClick={() => requestIntent('record')}
        title="Start recording (or hold `)"
      >
        to start
      </KeyHint>
      <KeyHint
        keys="T"
        onClick={() => requestIntent('text')}
        title="Compose text (or press T)"
      >
        text
      </KeyHint>
      <KeyHint
        keys="D"
        onClick={() => requestIntent('task')}
        title="Create a task (or press D)"
      >
        task
      </KeyHint>
      {!isRoot && (
        <KeyHint
          keys="N"
          onClick={onCreateStream}
          title="Create a stream here (or press N)"
        >
          stream
        </KeyHint>
      )}
    </div>
  );
}
