/* Parley — the five screens that close the dead ends: full search results, what
   other people have shared with you, the archive shelf, one saved prompt, and
   one file. Commit model: INSTANT on all five — nothing here is a form, every
   action confirms itself through App.jsx, and the irreversible ones open a
   confirm dialog there.

   The two record screens exist because a row that names a thing and cannot open
   it is a dead end: a prompt you could see but not read, and a file cited by a
   turn with nowhere to go. Both derive their relations rather than storing
   them — which threads carry this file, which turns cited it. */
(() => {
  const {
    Button, Badge, Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell, Input, Select, Separator,
    Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent,
  } = window.OriginDesignSystem_7c998b;

  /* A record the route resolves to but the fixture no longer holds — it was
     deleted while you were looking at it. Not the same thing as an
     unregistered path, which is RouteNotBuilt. */
  function MissingRecord({ what, where, label, onNavigate }) {
    return (
      <div className="pl-page">
        <Card>
          <CardPanel>
            <Empty>
              <EmptyHeader>
                <EmptyMedia variant="icon"><Icon name="file-question" size={18} /></EmptyMedia>
                <EmptyTitle>That {what} is gone</EmptyTitle>
                <EmptyDescription>It was deleted, so there is nothing here to show. Everything else is where it was.</EmptyDescription>
              </EmptyHeader>
              <EmptyContent><Button onClick={() => onNavigate(where)}>{label}</Button></EmptyContent>
            </Empty>
          </CardPanel>
        </Card>
      </div>
    );
  }

  /* ── Search results ────────────────────────────────────────────────── */

  function SearchScreen({ data, query, kind, onQuery, onKind, onNavigate }) {
    const groups = searchAll(data, query);
    const shown = groups.filter((g) => (kind === "all" || g.kind === kind) && g.items.length);
    const total = searchTotal(groups);
    const inScope = shown.reduce((n, g) => n + g.items.length, 0);
    const typed = query.trim().length > 0;
    const dirty = typed || kind !== "all";
    const clear = () => { onQuery(""); onKind("all"); };
    const counts = { threads: data.threads.length, projects: data.projects.length, files: data.files.length, prompts: data.prompts.length };

    return (
      <div className="pl-page">
        <PageHead
          title="Search results"
          note={"Everything in " + WORKSPACE.name + " you can open: chats and their messages, projects and their instructions, files and their notes, saved prompts. ⌘K jumps to one record; this is the whole list."}
        />
        <FilterBar query={query} onQuery={onQuery} placeholder="Search chats, projects, files, prompts" dirty={dirty} onClear={clear}
          selects={[{ id: "kind", label: "Kind", value: kind, onChange: onKind, items: [{ value: "all", label: "All results" }].concat(SEARCH_KINDS) }]} />

        {!typed ? (
          <Card>
            <CardPanel>
              <Empty>
                <EmptyHeader>
                  <EmptyMedia variant="icon"><Icon name="search" size={18} /></EmptyMedia>
                  <EmptyTitle>Type something to search</EmptyTitle>
                  <EmptyDescription>
                    {SEARCH_KINDS.map((k) => counts[k.value] + " " + k.label.toLowerCase()).join(" · ")} are searchable. Message bodies are read too, so a phrase from a conversation finds the thread it is in.
                  </EmptyDescription>
                </EmptyHeader>
              </Empty>
            </CardPanel>
          </Card>
        ) : inScope ? (
          <>
            {shown.map((group) => (
              <Card className="pl-card-full" key={group.kind}>
                <CardHeader>
                  <CardTitle>{labelOf(SEARCH_KINDS, group.kind)}</CardTitle>
                  <CardDescription>
                    {group.items.length} of {counts[group.kind]} {labelOf(SEARCH_KINDS, group.kind).toLowerCase()} match “{query.trim()}”.
                  </CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="pl-stack--tight" style={{ display: "flex", flexDirection: "column" }}>
                    {group.items.map((item) => (
                      <div className={"pl-setting" + (item.recessed ? " pl-row--recessed" : "")} key={item.id}>
                        <span className="pl-setting__text">
                          <button type="button" className="pl-setting__name pl-link" onClick={() => onNavigate(item.route)}>{item.title}</button>
                          <span className="pl-record__meta">{item.meta}</span>
                          <span className="pl-record__meta">{item.why}</span>
                        </span>
                        <Button size="xs" variant="outline" onClick={() => onNavigate(item.route)}>Open</Button>
                      </div>
                    ))}
                  </div>
                </CardPanel>
              </Card>
            ))}
            <p className="pl-foot">
              {inScope} {inScope === 1 ? "match" : "matches"} for “{query.trim()}”
              {kind === "all"
                ? " across " + shown.length + " of the " + SEARCH_KINDS.length + " kinds searched"
                : " in " + labelOf(SEARCH_KINDS, kind).toLowerCase() + " — " + total + " across everything"}
            </p>
          </>
        ) : (
          <Card>
            <NoResults
              title={"Nothing matches “" + query.trim() + "”"}
              description={kind === "all"
                ? "No chat, project, file or prompt in " + WORKSPACE.name + " holds that."
                : total + " " + (total === 1 ? "match" : "matches") + " elsewhere, but none in " + labelOf(SEARCH_KINDS, kind).toLowerCase() + "."}
              onClear={clear}
            />
          </Card>
        )}
      </div>
    );
  }

  /* ── Shared with me ────────────────────────────────────────────────── */

  function SharedScreen({ data, user, onNavigate, onBranch }) {
    const now = data.now;
    const threads = sharedThreads(data.threads, user.id).slice().sort((a, b) => THREAD_FLAGS.lastActivityAt(b) - THREAD_FLAGS.lastActivityAt(a));
    const projects = sharedProjects(data.projects, user.id);
    const sharers = threads.concat([]).reduce((ids, t) => (ids.indexOf(t.ownerId) > -1 ? ids : ids.concat([t.ownerId])), [])
      .concat(projects.map((p) => p.ownerId)).reduce((ids, id) => (ids.indexOf(id) > -1 ? ids : ids.concat([id])), []);

    return (
      <div className="pl-page">
        <PageHead
          title="Shared with me"
          note="Threads and projects other people have opened to the workspace. You can read every turn and branch from any of them; replies go into a thread of your own, never into theirs."
        />

        <AnchorRow items={[
          { label: "Threads", value: String(threads.length), qualifier: threads.length ? "Last reply " + formatAge(THREAD_FLAGS.lastActivityAt(threads[0]), now) : "Nothing shared with you yet" },
          { label: "Projects", value: String(projects.length), qualifier: "Their instructions and files come with them" },
          { label: "People", value: String(sharers.length), qualifier: "of the " + (data.people.length - 1) + " others in " + WORKSPACE.name },
        ]} />

        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>Threads</CardTitle>
            <CardDescription>Read-only. Branching copies the conversation up to a turn into a thread you own.</CardDescription>
          </CardHeader>
          {threads.length ? (
            <>
              <CardPanel className="pl-card-table">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Thread</TableHead>
                      <TableHead>Shared as</TableHead>
                      <TableHead className="pl-drop-md">Project</TableHead>
                      <TableHead className="pl-num pl-drop-md">Turns</TableHead>
                      <TableHead>Last reply</TableHead>
                      <TableHead className="pl-actions-head">Actions</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {threads.map((thread) => {
                      const project = thread.projectId ? projectById(data.projects, thread.projectId) : null;
                      return (
                        <TableRow key={thread.id}>
                          <TableCell>
                            <span className="pl-record">
                              <button type="button" className="pl-record__name pl-link" onClick={() => onNavigate(resolvePath("/chats/:id", { id: thread.id }))}>{thread.title}</button>
                              <span className="pl-record__meta">{personById(data.people, thread.ownerId).name} · {personById(data.people, thread.ownerId).role}</span>
                            </span>
                          </TableCell>
                          <TableCell><VisibilityBadge value={thread.visibility} /></TableCell>
                          <TableCell className="pl-drop-md">
                            {project
                              ? <button type="button" className="pl-link" onClick={() => onNavigate(resolvePath("/projects/:id", { id: project.id }))}>{project.name}</button>
                              : <span className="pl-muted">None</span>}
                          </TableCell>
                          <TableCell className="pl-num pl-drop-md">{threadBilling(thread, data.files).rows.length}</TableCell>
                          <TableCell title={formatAbsolute(THREAD_FLAGS.lastActivityAt(thread))}><span className="pl-when">{formatWhen(THREAD_FLAGS.lastActivityAt(thread), now)}</span></TableCell>
                          <TableCell className="pl-actions">
                            <span className="pl-actions__row">
                              <Button size="xs" variant="outline" onClick={() => onBranch(thread)}><Icon name="git-branch" size={13} />Branch</Button>
                            </span>
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                </Table>
              </CardPanel>
              <CardFooter>
                <span className="pl-foot">
                  {threads.length} of the {liveThreads(data.threads).length} live threads in {WORKSPACE.name} are other people's and open to you.
                </span>
              </CardFooter>
            </>
          ) : (
            <CardPanel>
              <Empty>
                <EmptyHeader>
                  <EmptyMedia variant="icon"><Icon name="users" size={18} /></EmptyMedia>
                  <EmptyTitle>Nobody has shared a thread with you</EmptyTitle>
                  <EmptyDescription>A thread appears here when its owner shares it with the workspace or puts a public link on it.</EmptyDescription>
                </EmptyHeader>
              </Empty>
            </CardPanel>
          )}
        </Card>

        {projects.length ? (
          <Card className="pl-card-full">
            <CardHeader>
              <CardTitle>Projects</CardTitle>
              <CardDescription>A chat started inside one of these is sent its instructions and its indexed files, the same as its owner's.</CardDescription>
            </CardHeader>
            <CardPanel>
              <div className="pl-stack--tight" style={{ display: "flex", flexDirection: "column" }}>
                {projects.map((project) => {
                  const inside = threadsInProject(data.threads, project.id);
                  const files = filesInProject(data.files, project.id);
                  const stuck = files.filter(FILE_FLAGS.needsAttention);
                  return (
                    <div className="pl-setting" key={project.id}>
                      <span className="pl-setting__text">
                        <button type="button" className="pl-setting__name pl-link" onClick={() => onNavigate(resolvePath("/projects/:id", { id: project.id }))}>{project.name}</button>
                        <span className="pl-record__meta">{personById(data.people, project.ownerId).name} · {inside.length} threads · {files.length} files{stuck.length ? " · " + stuck.length + " the index could not read" : ""}</span>
                        <span className="pl-record__meta">{project.purpose}</span>
                      </span>
                      <Button size="xs" variant="outline" onClick={() => onNavigate(resolvePath("/projects/:id", { id: project.id }))}>Open</Button>
                    </div>
                  );
                })}
              </div>
            </CardPanel>
          </Card>
        ) : null}
      </div>
    );
  }

  /* ── The archive shelf ─────────────────────────────────────────────── */

  function ArchivedScreen({ data, user, onNavigate, onRun }) {
    const now = data.now;
    const archived = archivedThreads(data.threads).slice().sort((a, b) => b.archivedAt - a.archivedAt);
    const rows = billingRows(archived, data.files);

    return (
      <div className="pl-page">
        <PageHead
          title="Archived chats"
          note="Out of the list, still yours. An archived thread keeps every turn and every attachment, and cannot take a new one until it is restored."
        />
        {archived.length ? (
          <Card className="pl-card-full">
            <CardPanel className="pl-card-table">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Thread</TableHead>
                    <TableHead className="pl-drop-md">Project</TableHead>
                    <TableHead className="pl-num pl-drop-md">Turns</TableHead>
                    <TableHead className="pl-num">Cost</TableHead>
                    <TableHead>Archived</TableHead>
                    <TableHead className="pl-actions-head">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {archived.map((thread) => {
                    const project = thread.projectId ? projectById(data.projects, thread.projectId) : null;
                    const billing = threadBilling(thread, data.files);
                    return (
                      <TableRow key={thread.id} className="pl-row--recessed">
                        <TableCell>
                          <span className="pl-record">
                            <button type="button" className="pl-record__name pl-link" onClick={() => onNavigate(resolvePath("/chats/:id", { id: thread.id }))}>{thread.title}</button>
                            <span className="pl-record__meta">{thread.messages.length} messages · last reply {formatAge(THREAD_FLAGS.lastActivityAt(thread), now)}</span>
                          </span>
                        </TableCell>
                        <TableCell className="pl-drop-md">
                          {project
                            ? <button type="button" className="pl-link" onClick={() => onNavigate(resolvePath("/projects/:id", { id: project.id }))}>{project.name}</button>
                            : <span className="pl-muted">None</span>}
                        </TableCell>
                        <TableCell className="pl-num pl-drop-md">{billing.rows.length}</TableCell>
                        <TableCell className="pl-num">{formatCost(billing.cost)}</TableCell>
                        <TableCell title={formatAbsolute(thread.archivedAt)}><span className="pl-when">{formatWhen(thread.archivedAt, now)}</span></TableCell>
                        <TableCell className="pl-actions">
                          <RowActions transitions={threadTransitions(thread)} onRun={(t) => onRun(thread, t)} label={"Actions for " + thread.title} />
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </CardPanel>
            <CardFooter>
              <span className="pl-foot">
                {archived.length} archived of {data.threads.length} threads · the {rows.length} turns they hold still count {formatCost(costOf(rows))} on the usage screen, because they really ran.
              </span>
            </CardFooter>
          </Card>
        ) : (
          <Card>
            <CardPanel>
              <Empty>
                <EmptyHeader>
                  <EmptyMedia variant="icon"><Icon name="archive" size={18} /></EmptyMedia>
                  <EmptyTitle>Nothing is archived</EmptyTitle>
                  <EmptyDescription>Archiving a thread takes it out of the list in the sidebar without deleting a turn. Every thread you own is still in that list.</EmptyDescription>
                </EmptyHeader>
                <EmptyContent><Button variant="outline" onClick={() => onNavigate("/")}>Back to chats</Button></EmptyContent>
              </Empty>
            </CardPanel>
          </Card>
        )}
      </div>
    );
  }

  /* ── One saved prompt ──────────────────────────────────────────────── */

  function PromptScreen({ prompt, data, user, onRun, onNavigate }) {
    const now = data.now;
    const stale = PROMPT_FLAGS.isStale(prompt, now);
    const author = personById(data.people, prompt.authorId);
    const sameCategory = data.prompts.filter((p) => p.category === prompt.category);
    const rank = data.prompts.slice().sort((a, b) => b.uses - a.uses).findIndex((p) => p.id === prompt.id) + 1;

    return (
      <div className="pl-page" style={{ maxWidth: "60rem" }}>
        <PageHead
          title={prompt.title}
          note={labelOf(PROMPT_CATEGORIES, prompt.category) + " · saved by " + author.name + " · shared with everyone in " + WORKSPACE.name + "."}
          actions={<RowActions transitions={promptTransitions(prompt)} onRun={(t) => onRun(prompt, t)} label={"Actions for " + prompt.title} />}
        />

        <AnchorRow items={[
          { label: "Uses", value: String(prompt.uses), qualifier: rank + (rank === 1 ? "st" : rank === 2 ? "nd" : rank === 3 ? "rd" : "th") + " most used of the " + data.prompts.length + " in the library" },
          { label: "Last used", value: formatWhen(prompt.lastUsedAt, now), qualifier: stale ? "Not in two months — this one is recessed in the library" : "Recently enough to stay in the composer's menu" },
          { label: "Length", value: formatTokens(estimateTokens(prompt.body)), qualifier: "tokens, dropped into the composer as they are" },
        ]} />

        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>The prompt</CardTitle>
            <CardDescription>Used as written. Nothing is appended, and the thread's own files and project instructions still go with it.</CardDescription>
          </CardHeader>
          <CardPanel>
            <p className="pl-instructions">{prompt.body}</p>
          </CardPanel>
          <CardFooter>
            <span className="pl-chips">
              <Button size="sm" onClick={() => onRun(prompt, { id: "use", label: "Use" })}>Use in a new chat</Button>
              <Button size="sm" variant="outline" onClick={() => onRun(prompt, { id: "edit", label: "Edit" })}>Edit</Button>
            </span>
            <span className="pl-foot" style={{ marginInlineStart: "auto" }}>
              {sameCategory.length} {labelOf(PROMPT_CATEGORIES, prompt.category).toLowerCase()} {sameCategory.length === 1 ? "prompt" : "prompts"} in the library
            </span>
          </CardFooter>
        </Card>

        {stale ? (
          <p className="pl-turn__note">
            <Icon name="clock" size={16} />
            Nobody has used this since {formatDay(prompt.lastUsedAt)}. It still works — it is just not one of the four the composer offers, which are the four most used.
          </p>
        ) : null}
      </div>
    );
  }

  /* ── One file ──────────────────────────────────────────────────────── */

  function FileScreen({ file, data, onRun, onNavigate }) {
    const now = data.now;
    const project = file.projectId ? projectById(data.projects, file.projectId) : null;
    const carrying = data.threads.filter((t) => (t.fileIds || []).indexOf(file.id) > -1);
    const citing = [];
    data.threads.forEach((thread) => thread.messages.forEach((message) => {
      if ((message.cites || []).indexOf(file.id) > -1) citing.push({ thread: thread, message: message });
    }));
    const inContext = FILE_FLAGS.inContext(file);
    const needs = FILE_FLAGS.needsAttention(file);

    return (
      <div className="pl-page" style={{ maxWidth: "64rem" }}>
        <PageHead
          title={file.name}
          note={file.note}
          actions={
            <span className="pl-chips">
              <StatusBadge values={FILE_STATUS} value={file.status} />
              <RowActions transitions={fileTransitions(file)} onRun={(t) => onRun(file, t)} label={"Actions for " + file.name} />
            </span>
          }
        />

        <AnchorRow items={[
          { label: "Size", value: formatBytes(file.bytes), qualifier: "Uploaded by " + personById(data.people, file.uploadedBy).name.split(" ")[0] + " on " + formatDay(file.at) },
          { label: "Tokens", value: inContext ? formatTokens(file.tokens) : "—", qualifier: inContext ? "Read again on every turn of every thread carrying it" : "Nothing indexed, so it costs nothing and contributes nothing" },
          { label: "Threads carrying it", value: String(carrying.length), qualifier: carrying.length ? "It is in their context now" : "Attach it in a composer to use it" },
          { label: "Turns citing it", value: String(citing.length), qualifier: citing.length ? "They read it when they ran" : "No answer has leaned on it yet" },
        ]} />

        {needs ? (
          <p className="pl-turn__note">
            <Icon name="triangle-alert" size={16} />
            {file.statusNote} Until that is fixed, every turn on the {carrying.length} {carrying.length === 1 ? "thread" : "threads"} below is answering without it.
          </p>
        ) : null}

        <div className="pl-columns">
          <div className="pl-col">
            <Card className="pl-card-full">
              <CardHeader>
                <CardTitle>Threads carrying it</CardTitle>
                <CardDescription>Attached, so it is re-read on every turn and counts against each thread's window.</CardDescription>
              </CardHeader>
              {carrying.length ? (
                <CardPanel className="pl-card-table">
                  <Table>
                    <TableHeader>
                      <TableRow>
                        <TableHead>Thread</TableHead>
                        <TableHead className="pl-num">Context</TableHead>
                        <TableHead>Last reply</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {carrying.map((thread) => (
                        <TableRow key={thread.id}>
                          <TableCell>
                            <span className="pl-record">
                              <button type="button" className="pl-record__name pl-link" onClick={() => onNavigate(resolvePath("/chats/:id", { id: thread.id }))}>{thread.title}</button>
                              <span className="pl-record__meta">{personById(data.people, thread.ownerId).name} · {labelOf(MODELS, thread.model)}</span>
                            </span>
                          </TableCell>
                          <TableCell className="pl-num">{formatTokens(contextUsed(thread, data.files))} / {formatTokens(contextMax(thread))}</TableCell>
                          <TableCell title={formatAbsolute(THREAD_FLAGS.lastActivityAt(thread))}><span className="pl-when">{formatWhen(THREAD_FLAGS.lastActivityAt(thread), now)}</span></TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </CardPanel>
              ) : (
                <CardPanel>
                  <p className="pl-rail__note">Nothing carries it. A file in the workspace costs nothing until it is attached to a thread{project ? " — though a chat started in " + project.name + " picks it up automatically." : "."}</p>
                </CardPanel>
              )}
            </Card>

            {citing.length ? (
              <Card className="pl-card-full">
                <CardHeader>
                  <CardTitle>Turns that cited it</CardTitle>
                  <CardDescription>An answer citing a file read it as it stood at that moment. Reindexing later does not change what was said.</CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="pl-stack--tight" style={{ display: "flex", flexDirection: "column" }}>
                    {citing.map((row) => (
                      <div className="pl-setting" key={row.thread.id + "/" + row.message.id}>
                        <span className="pl-setting__text">
                          <button type="button" className="pl-setting__name pl-link" onClick={() => onNavigate(resolvePath("/chats/:id", { id: row.thread.id }))}>{row.thread.title}</button>
                          <span className="pl-record__meta">
                            {labelOf(MODELS, row.message.model || row.thread.model)} · {formatWhen(row.message.at, now)} · {personById(data.people, row.thread.ownerId).name}
                          </span>
                        </span>
                        <StatusBadge values={MESSAGE_STATUS} value={row.message.status} />
                      </div>
                    ))}
                  </div>
                </CardPanel>
              </Card>
            ) : null}
          </div>

          <div className="pl-col">
            <Card className="pl-card-full">
              <CardHeader>
                <CardTitle>Where it lives</CardTitle>
                <CardDescription>{project ? "On a project, so every chat started there is sent it." : "In the workspace, so it is attached one thread at a time."}</CardDescription>
              </CardHeader>
              <CardPanel>
                <dl className="pl-defs">
                  <div>
                    <dt>Project</dt>
                    <dd>
                      {project
                        ? <button type="button" className="pl-link" onClick={() => onNavigate(resolvePath("/projects/:id", { id: project.id }))}>{project.name}</button>
                        : <span className="pl-muted">Workspace</span>}
                    </dd>
                  </div>
                  <div><dt>Uploaded</dt><dd title={formatAbsolute(file.at)}>{formatDay(file.at)}</dd></div>
                  <div><dt>By</dt><dd>{personById(data.people, file.uploadedBy).name}</dd></div>
                  <div><dt>Index</dt><dd>{statusValue(FILE_STATUS, file.status).label}</dd></div>
                </dl>
              </CardPanel>
              <CardFooter>
                <Button size="sm" variant="ghost" onClick={() => onNavigate("/files")}>All files<Icon name="arrow-right" size={13} /></Button>
              </CardFooter>
            </Card>
          </div>
        </div>
      </div>
    );
  }

  Object.assign(window, { SearchScreen, SharedScreen, ArchivedScreen, PromptScreen, FileScreen, MissingRecord });
})();
