import type { ReactNode } from 'react';
import { useCallback } from 'react';
import { useSearchParams } from 'react-router';
import { useFilesRefresh } from '../../channels';
import { FileViewerProvider } from '../../apps/FileViewer';
import { EmbeddableChat } from '../../apps/Chat/EmbeddableChat';

type SetSearchParams = ReturnType<typeof useSearchParams>[1];

const onReplaceView = (setSearchParams: SetSearchParams) =>
  (viewPath: string, viewRoot: string, ephemeralPath: string, ephemeralRoot: string) => {
    setSearchParams((prev) => {
      const next = new URLSearchParams(prev);
      next.set('view', viewPath);
      next.set('ephemeral', ephemeralPath);
      next.set('ephemeralRoot', ephemeralRoot);
      next.delete('ephemeral2');
      next.delete('ephemeral2Root');
      next.delete('ephemeral2Auto');
      return next;
    });
  };

export function ViewerProvider({ children }: { children: ReactNode }) {
  const [searchParams, setSearchParams] = useSearchParams();
  const viewPath = searchParams.get('view') ?? '';
  const fileName = viewPath.split('/').pop() ?? '';

  const onOpenFile = (filePath: string, root: string) => {
    setSearchParams((prev) => {
      const next = new URLSearchParams(prev);
      next.set('ephemeral', filePath);
      next.set('ephemeralRoot', root);
      return next;
    });
  };

  return (
    <FileViewerProvider filePath={viewPath} fileName={fileName} onOpenFile={onOpenFile} onReplaceView={onReplaceView(setSearchParams)}>
      {children}
    </FileViewerProvider>
  );
}

export function EphemeralProvider({ children }: { children: ReactNode }) {
  const [searchParams, setSearchParams] = useSearchParams();
  const ephemeralPath = searchParams.get('ephemeral') ?? '';
  const ephemeralRoot = searchParams.get('ephemeralRoot') ?? 'home';
  const fileName = ephemeralPath.split('/').pop() ?? '';

  const onOpenFile = (filePath: string, root: string) => {
    setSearchParams((prev) => {
      const next = new URLSearchParams(prev);
      next.set('ephemeral2', filePath);
      next.set('ephemeral2Root', root);
      next.set('ephemeral2Auto', '1');
      return next;
    });
  };

  return (
    <FileViewerProvider filePath={ephemeralPath} fileName={fileName} root={ephemeralRoot} onOpenFile={onOpenFile} onReplaceView={onReplaceView(setSearchParams)}>
      {children}
    </FileViewerProvider>
  );
}

export function Ephemeral2Provider({ children }: { children: ReactNode }) {
  const [searchParams, setSearchParams] = useSearchParams();
  const ephemeral2Path = searchParams.get('ephemeral2') ?? '';
  const ephemeral2Root = searchParams.get('ephemeral2Root') ?? 'home';
  const ephemeral2Auto = searchParams.get('ephemeral2Auto') === '1';
  const fileName = ephemeral2Path.split('/').pop() ?? '';

  return (
    <FileViewerProvider filePath={ephemeral2Path} fileName={fileName} root={ephemeral2Root} autoPlay={ephemeral2Auto} onReplaceView={onReplaceView(setSearchParams)}>
      {children}
    </FileViewerProvider>
  );
}

export const ChatEphemeralBody = () => {
  const [searchParams] = useSearchParams();
  const [, bumpFilesRefresh] = useFilesRefresh();
  const chatContext = searchParams.get('chatContext') ?? '';
  const chatType = searchParams.get('chatType') as 'file' | 'folder' | null;

  const cwdPath = chatType === 'file'
    ? chatContext.substring(0, chatContext.lastIndexOf('/')) || '/'
    : chatContext;

  const tag = chatType === 'file' ? 'file' : 'folder';
  const path = chatContext.replace(/^\//, '');
  const message = chatType === 'file'
    ? `[${tag}: ${path}] Let's talk about this file`
    : `[${tag}: ${path || '/'}] consider, for this session, this directory as your current working directory`;

  const handleMessageComplete = useCallback(() => {
    bumpFilesRefresh();
  }, [bumpFilesRefresh]);

  return (
    <EmbeddableChat
      className="h-full"
      cwd={{ root: 'home', path: cwdPath.replace(/^\//, '') || '/' }}
      defaultInput={message}
      onMessageComplete={handleMessageComplete}
    />
  );
};
