<script lang="ts">
  /**
   * The Mail Center — notifications as an inbox, plus the Friend Request
   * Manager with its Approve / Deny buttons.
   *
   * Folders map onto notification types. The "requests" folder is a different
   * endpoint (`/api/v1/follow_requests`) because pending requests aren't
   * notifications once they've been read.
   */
  import { untrack } from 'svelte'
  import type { Account, Notification } from '$lib/api/types'
  import { useAppServices } from '$lib/app-services'
  import { Feed } from '$lib/stores/feed.svelte'
  import { displayNameOf, fullHandle, profilePath } from '$lib/util/profile'
  import { toPlainText } from '$lib/util/html'
  import { stampDate } from '$lib/util/time'
  import Module from '$components/common/Module.svelte'
  import Pager from '$components/common/Pager.svelte'
  import Avatar from '$components/common/Avatar.svelte'

  interface Props {
    folder?: string
  }

  let { folder = 'inbox' }: Props = $props()

  const { endpoints, session } = useAppServices()
  interface Folder {
    key: string
    label: string
    icon: string
    /** Notification types this folder shows; empty means everything. */
    types: string[]
  }

  const FOLDERS: Folder[] = [
    { key: 'inbox', label: 'Inbox', icon: '📥', types: [] },
    { key: 'mentions', label: 'Messages', icon: '✉', types: ['mention'] },
    { key: 'requests', label: 'Friend Requests', icon: '➕', types: [] },
    { key: 'follows', label: 'New Friends', icon: '👥', types: ['follow'] },
    { key: 'kudos', label: 'Kudos', icon: '★', types: ['favourite'] },
    { key: 'reposts', label: 'Reposts', icon: '↻', types: ['reblog'] },
  ]

  const active = $derived(FOLDERS.find((entry) => entry.key === folder) ?? FOLDERS[0])
  const isRequests = $derived(active.key === 'requests')

  let notifications = $state<Feed<Notification>>(new Feed<Notification>(async () => ({ items: [], links: {} })))
  let requests = $state<Feed<Account>>(new Feed<Account>(async () => ({ items: [], links: {} })))
  let busyIds = $state<Record<string, boolean>>({})
  let actionError = $state<string | null>(null)

  const VERB: Record<string, string> = {
    mention: 'sent you a message',
    follow: 'added you as a friend',
    follow_request: 'wants to be your friend',
    favourite: 'gave your entry kudos',
    reblog: 'reposted your entry',
    poll: 'closed a poll you voted in',
    status: 'posted a new entry',
    update: 'edited an entry you interacted with',
    'pleroma:emoji_reaction': 'reacted to your entry',
  }

  $effect(() => {
    const key = active.key
    const types = active.types
    if (!session.signedIn) return

    untrack(() => {
      if (key === 'requests') {
        requests = new Feed<Account>((cursor) => endpoints.fetchFollowRequests(session.api, cursor))
        void requests.reload()
      } else {
        notifications = new Feed<Notification>((cursor) =>
          endpoints.fetchNotifications(session.api, cursor, types.length > 0 ? types : undefined),
        )
        void notifications.reload()
      }
      document.title = `${key === 'requests' ? 'Friend Requests' : 'Mail Center'} | plspace`
    })
  })

  async function respond(account: Account, approve: boolean): Promise<void> {
    if (busyIds[account.id]) return
    busyIds = { ...busyIds, [account.id]: true }
    actionError = null
    try {
      await (approve ? endpoints.authorizeFollowRequest : endpoints.rejectFollowRequest)(
        session.api,
        account.id,
      )
      requests.remove(account.id)
    } catch (cause) {
      actionError = cause instanceof Error ? cause.message : 'That didn’t work.'
    } finally {
      busyIds = { ...busyIds, [account.id]: false }
    }
  }
</script>

<div class="page mail-page" data-folder={active.key}>
  <h1 class="page-title">Mail Center</h1>
  <p class="page-subtitle">
    {isRequests ? 'Friend Request Manager' : active.label}
  </p>

  {#if !session.signedIn}
    <p class="notice">
      <a href="#/login">Sign in</a> to read your mail.
    </p>
  {:else}
    <div class="layout--split">
      <div class="layout-column layout-column--left">
        <Module title="Folders" flush>
          <ul class="mail-folders">
            {#each FOLDERS as entry (entry.key)}
              <li class="mail-folder">
                <a
                  class="mail-folder-link"
                  href={entry.key === 'inbox' ? '#/mail' : `#/mail/${entry.key}`}
                  aria-current={entry.key === active.key ? 'page' : undefined}
                >
                  <span class="action-list-icon" aria-hidden="true">{entry.icon}</span>
                  <span class="mail-folder-label">{entry.label}</span>
                </a>
              </li>
            {/each}
          </ul>
        </Module>
      </div>

      <div class="layout-column layout-column--main">
        {#if actionError}
          <p class="error-note" role="alert">{actionError}</p>
        {/if}

        {#if isRequests}
          <Module title="Approve or Deny Your Friend Requests" variant="band">
            {#if requests.items.length > 0}
              <p class="mail-listing-count">
                Listing 1&ndash;{requests.items.length} of {requests.items.length}
              </p>
            {/if}

            <table class="mail-table">
              <thead>
                <tr>
                  <th scope="col">From</th>
                  <th scope="col">Confirmation</th>
                </tr>
              </thead>
              <tbody>
                {#each requests.items as account (account.id)}
                  <tr class="mail-row" data-kind="follow_request" data-account={account.acct}>
                    <td class="mail-table-from">
                      <a href={profilePath(account)}>
                        <Avatar {account} plain />
                      </a>
                    </td>
                    <td>
                      <strong>
                        <a href={profilePath(account)}>{displayNameOf(account)}</a>
                      </strong>
                      wants to be your friend!
                      <div class="person-row-handle">{fullHandle(account, session.host)}</div>
                      <div class="mail-table-actions">
                        <button
                          type="button"
                          class="button"
                          disabled={busyIds[account.id]}
                          onclick={() => void respond(account, true)}
                        >
                          Approve
                        </button>
                        <button
                          type="button"
                          class="button"
                          disabled={busyIds[account.id]}
                          onclick={() => void respond(account, false)}
                        >
                          Deny
                        </button>
                        <a class="button" href={`#/compose?to=${encodeURIComponent(account.acct)}`}>
                          Send Message
                        </a>
                      </div>
                    </td>
                  </tr>
                {/each}
              </tbody>
            </table>

            <Pager feed={requests} label="View More Requests" emptyText="No pending friend requests." />
          </Module>
        {:else}
          <Module title={active.label} variant="band">
            <table class="mail-table">
              <thead>
                <tr>
                  <th scope="col">Date</th>
                  <th scope="col">From</th>
                  <th scope="col">Subject</th>
                </tr>
              </thead>
              <tbody>
                {#each notifications.items as item (item.id)}
                  <tr class="mail-row" data-kind={item.type} data-account={item.account.acct}>
                    <td class="mail-table-date">{stampDate(item.created_at)}</td>
                    <td class="mail-table-from">
                      <a href={profilePath(item.account)}>
                        <Avatar account={item.account} plain />
                      </a>
                    </td>
                    <td class="mail-table-subject">
                      <strong>
                        <a href={profilePath(item.account)}>{displayNameOf(item.account)}</a>
                      </strong>
                      {VERB[item.type] ?? item.type}
                      {#if item.status}
                        <p class="mail-table-excerpt">
                          <a href={`#/blog/${item.status.id}`}>
                            {toPlainText(item.status.spoiler_text || item.status.content).slice(0, 140) ||
                              '(no text)'}
                          </a>
                        </p>
                      {/if}
                    </td>
                  </tr>
                {/each}
              </tbody>
            </table>

            <Pager feed={notifications} label="View More Mail" emptyText="Your inbox is empty." />
          </Module>
        {/if}
      </div>
    </div>
  {/if}
</div>
