import { useCoreServices } from '@learnitive/context';
import { Button, FunMissing } from '@learnitive/ui-components';
import { useAtomValue } from 'jotai';
import React from 'react';
import { ContentSection } from '../components/common/content-section';
import { suggestedProjectFileName } from '../common/project-file-suggestion';
import { PageHeader } from '../components/common/page-header';
import { NoticeView } from '../components/feedback/notice-view';
import { ProjectZipActions } from '../components/project-zip-actions';
import {
  NotesTable,
  type NotesTableNote,
} from '../components/notes-table/notes-table';
import { AppHeader } from '../layout/app-header';
import { PageContentContainer } from '../layout/main-content-container';

/**
 * Project home for the active Learnitive workspace. Every visible project file
 * is listed here; Markdown is supported but is no longer the controlling
 * workspace model.
 */
export function PageWsHome() {
  const coreServices = useCoreServices();
  const currentWsName = useAtomValue(
    coreServices.workspaceState.$currentWsName,
  );
  const projectFiles = useProjectFilesTableData();
  const workspaces = useAtomValue(coreServices.workspaceState.$workspaces);
  const newFileName = suggestedProjectFileName(workspaces.find((item) => item.name === currentWsName)?.metadata);

  const onNewFile = () =>
    coreServices.commandDispatcher.dispatch(
      'command::ui:create-file-dialog',
      { prefillName: newFileName, pathPrefix: undefined },
      'ui',
    );
  return (
    <>
      <AppHeader />
      <PageContentContainer testId="page-ws-home">
        {currentWsName ? (
          projectFiles.length > 0 ? (
            <ContentSection hasPadding>
              <div className="mx-auto flex w-full max-w-4xl flex-col gap-4">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <h2 className="wrap-anywhere min-w-0 font-semibold text-2xl tracking-tight">
                    {currentWsName}
                  </h2>
                  <div className="flex shrink-0 items-center gap-1.5">
                    <Button onClick={onNewFile}>
                      {t.app.pageWsHome.newNoteButton}
                    </Button>
                    <ProjectZipActions workspaceName={currentWsName} />
                  </div>
                </div>
                <NotesTable notes={projectFiles} />
              </div>
            </ContentSection>
          ) : (
            <ContentSection hasPadding>
              <PageHeader title={`${currentWsName}`} />
              <div className="py-4 text-center text-muted-foreground text-sm">
                {t.app.pageWsHome.noNotesMessage}
              </div>
              <div className="mb-4 flex justify-center">
                <div className="flex items-center gap-1.5">
                  <Button onClick={onNewFile}>
                    {t.app.pageWsHome.newNoteButton}
                  </Button>
                  <ProjectZipActions workspaceName={currentWsName} />
                </div>
              </div>
            </ContentSection>
          )
        ) : (
          <ContentSection hasPadding>
            <NoticeView
              title={t.app.pageWorkspaceNotFound.title}
              description={<FunMissing />}
              actions={[
                {
                  label: t.app.pageWorkspaceNotFound.createWorkspaceButton,
                  onClick: () =>
                    coreServices.commandDispatcher.dispatch(
                      'command::ui:create-workspace-dialog',
                      null,
                      'ui',
                    ),
                },
                {
                  label: t.app.pageWorkspaceNotFound.switchWorkspaceButton,
                  variant: 'outline',
                  onClick: () =>
                    coreServices.commandDispatcher.dispatch(
                      'command::ui:switch-workspace',
                      null,
                      'ui',
                    ),
                },
              ]}
            />
          </ContentSection>
        )}
      </PageContentContainer>
    </>
  );
}

/**
 * Assembles project-file rows from the workspace listing, user activity and
 * file stats. Rows are pre-ordered by last-opened recency.
 */
function useProjectFilesTableData(): NotesTableNote[] {
  const coreServices = useCoreServices();
  const wsPaths = useAtomValue(coreServices.workspaceState.$wsPaths);
  const allRecentWsPaths = useAtomValue(
    coreServices.userActivityService.$allRecentWsPaths,
  );
  const starredPaths = useAtomValue(
    coreServices.userActivityService.$starredWsPaths,
  );
  const stats = useAtomValue(coreServices.workspaceState.$noteFileStats);

  return React.useMemo(() => {
    const lastOpenedByWsPath = new Map(
      allRecentWsPaths.map(({ wsPath, timestamp }) => [wsPath, timestamp]),
    );
    const starredSet = new Set(starredPaths);

    return wsPaths
      .map((filePath): NotesTableNote => {
        const stat = stats.get(filePath.wsPath);
        const parent = filePath.getParent();
        const dirPath =
          parent && !parent.isRoot ? parent.path.replace(/\/$/, '') : '';
        return {
          wsPath: filePath.wsPath,
          fileName: filePath.fileName,
          dirPath,
          href: coreServices.navigation.toUri({
            route: 'editor',
            payload: { wsPath: filePath.wsPath },
          }),
          isStarred: starredSet.has(filePath.wsPath),
          lastOpenedAt: lastOpenedByWsPath.get(filePath.wsPath),
          modifiedAt: stat?.mtime,
        };
      })
      .sort(
        (a, b) =>
          (b.lastOpenedAt ?? 0) - (a.lastOpenedAt ?? 0) ||
          a.fileName.localeCompare(b.fileName),
      );
  }, [
    wsPaths,
    allRecentWsPaths,
    starredPaths,
    stats,
    coreServices.navigation,
  ]);
}
