<script lang="ts">
  import Nav from '../../Nav.svelte';
  import Atom from './Atom.svelte';
  import Pos from './Pos.svelte';
  import Edge from './Edge.svelte';
  import Contents from './Contents.svelte';
  import Meta from './Meta.svelte';
  import type { Deps, Hunk } from './Types';
  export let data: {
    deps: Deps;
    authors: { login?: string; key: string }[];
    hash: string;
    repo: string;
    owner: string;
    header: {
      message: string;
      timestamp: string;
      description: string | null;
    };
    hunks: Hunk[];
  };
  let date = new Intl.DateTimeFormat('en-US', {
    dateStyle: 'medium',
    timeStyle: 'short'
  }).format(new Date(data.header.timestamp));
</script>

<svelte:head>
  <title>{data.owner} / {data.repo} - {data.hash}</title>
</svelte:head>

<div class="p-3">
  <Nav user={data.owner} repo={data.repo} link={true} />

  <h1 class="mt-5">{data.header.message}</h1>

  <div class="flex items-center py-3 gap-5">
    {#if data.authors?.length}
      {#if data.authors[0]?.login}
        <img
          class="profile-picture"
          src="/identicon/{data.authors[0].login}"
          alt="Profile picture of {data.authors[0].login}" />
      {:else}
        <img alt="" class="profile-picture" src="/identicon/question/small" />
      {/if}
    {:else}
      <img class="profile-picture" src="/identicon/question/small" alt="unknown author" />
    {/if}
    <div class="flex flex-col">
      <div>
        {#each data.authors as a, i}{#if i > 0},
          {/if}{#if a.login}<a href="/{a.login}">{a.login}</a>{:else}
            <span class="font-mono">{a.key}</span>
          {/if}{/each}
      </div>
      <div>
        {date}
      </div>
      <div>
        <code class="hash">{data.hash}</code>
      </div>
    </div>
  </div>

  <h2 class="mt-8">Dependencies</h2>
  <ul class="list my-3">
    {#if data.deps?.hashes?.length}
      {#each data.deps.hashes.slice(2) as d, i}
        {#if i >= data.deps?.deps.length + (data.deps?.known?.length || 0)}<li class="list-row">
            [*]&nbsp<a class="link" href={d}><code class="hash">{d}</code></a>
          </li>
        {:else}
          <li>[{i + 2}]&nbsp<a class="link" href={d}><code class="hash">{d}</code></a></li>
        {/if}
      {/each}
    {/if}
  </ul>

  <h2 class="mt-8">Change contents</h2>
  <ul class="py-3">
    {#if data.hunks}
      {#each data.hunks as l}
        <li class="">
          {#if l.FileAdd}
            <h3>File addition: <Meta m={l.FileAdd.meta} /></h3>
            <div class="context">
              <div class="change-newvertex-up">
                {#each l.FileAdd.context as cc}<Pos deps={data.deps} c={cc} />{/each}
              </div>
            </div>
            <div class="p-3">
              <Contents contents={l.FileAdd.contents} />
            </div>
          {:else if l.FileMove}
            <h6>
              File move:{#each l.FileMove.old as m}
                <Meta {m} />{/each} → <Meta m={l.FileMove.meta} />
            </h6>
            <div class="px-3">
              <div class="context">
                <div class="change-newvertex-up">
                  {#each l.FileMove.up as cc}<Pos deps={data.deps} c={cc} />{/each}
                </div>
              </div>
              <div class="context">
                <div class="change-newvertex-down">
                  {#each l.FileMove.down as cc}<Pos deps={data.deps} c={cc} />{/each}
                </div>
              </div>
            </div>
          {:else if l.FileDel}
            <h6>
              File deletion:{#each l.FileDel.deleted_names as m}
                <Meta {m} />{/each}
            </h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.FileDel.del} />
              {#if l.FileDel.content_edges.length}
                <div class="context">
                  {#each l.FileDel.content_edges as e, n}{#if n > 0},
                    {/if}<Edge edge={e} deps={data.deps} />{/each}
                </div>
              {/if}
            </div>
            <div class="p-3">
              <Contents contents={l.FileDel.content} />
            </div>
          {:else if l.FileUndel}
            <h6>
              File un-deletion:{#each l.FileUndel.undel_names as m}
                <Meta {m} />{/each}
            </h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.FileUndel.undel} />
              <div class="context">
                {#each l.FileUndel.content_edges as e, n}{#if n > 0},
                  {/if}<Edge edge={e} deps={data.deps} />{/each}
              </div>
            </div>
            <div class="p-3">
              <Contents contents={l.FileUndel.content} />
            </div>
          {:else if l.SolveNameConflict}
            <h6>
              Solving a name conflict:{#each l.SolveNameConflict.old as m}
                <Meta {m} />{/each}
            </h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.SolveNameConflict.name} />
            </div>
          {:else if l.UnsolveNameConflict}
            <h6>
              Unsolving a name conflict:{#each l.UnsolveNameConflict.old as m}
                <Meta {m} />{/each}
            </h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.UnsolveNameConflict.name} />
            </div>
          {:else if l.Edit}
            <h6>Edit in {l.Edit.path} at line {l.Edit.line}</h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.Edit.atom} />
            </div>
            <div class="px-3 pb-0">
              <Contents contents={l.Edit.contents} />
            </div>
          {:else if l.Replacement}
            <h6>Replacement in {l.Replacement.path} at line {l.Replacement.line}</h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={{ EdgeMap: l.Replacement.del }} />
              <Contents contents={l.Replacement.del_contents} />
            </div>
            <div class="px-3 py-2 m-0">
              <Atom deps={data.deps} atom={{ NewVertex: l.Replacement.ins }} />
              <Contents contents={l.Replacement.ins_contents} />
            </div>
          {:else if l.SolveOrderConflict}
            <h6>
              Solving an order conflict in {l.SolveOrderConflict.path} at line {l.SolveOrderConflict
                .line}
            </h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.SolveOrderConflict.atom} />
            </div>
            <div class="p-3 pb-0">
              <Contents contents={l.SolveOrderConflict.contents} />
            </div>
          {:else if l.UnsolveOrderConflict}
            <h6>
              Unsolving an order conflict in {l.UnsolveOrderConflict.path} at line {l
                .UnsolveOrderConflict.line}
            </h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.UnsolveOrderConflict.atom} />
            </div>
            <div class="p-3 pb-0">
              <Contents contents={l.UnsolveOrderConflict.contents} />
            </div>
          {:else if l.ResurrectZombie}
            <h6>
              Resurrecting zombies in {l.ResurrectZombie.path} at line {l.ResurrectZombie.line}
            </h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.ResurrectZombie.atom} />
            </div>
            <div class="p-3 pb-0">
              <Contents contents={l.ResurrectZombie.contents} />
            </div>
          {:else if l.AddRoot}
            <h6>Add root</h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.AddRoot.name} />
              <Atom deps={data.deps} atom={l.AddRoot.atom} />
            </div>
          {:else if l.DelRoot}
            <h6>Del root</h6>
            <div class="px-3">
              <Atom deps={data.deps} atom={l.DelRoot.name} />
              <Atom deps={data.deps} atom={l.DelRoot.atom} />
            </div>
          {/if}
        </li>
      {/each}
    {:else}
      This change cannot be displayed, possibly because it contains binary files.
    {/if}
  </ul>
</div>

<style global>
  img.profile-picture {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    padding: 0;
    background-color: white;
  }
  :global {
    .hash {
      color: var(--color-neutral-500);
    }
    .change-context,
    .permissions {
      font-size: 90%;
    }
    .change-newvertex-up::before {
      content: '↑';
    }
    .change-newvertex-down::before {
      content: '↓';
    }
    div.change_addition::before {
      content: '+';
    }
    div.change_deletion::before {
      content: '-';
    }

    div.change_addition::before,
    div.change_deletion::before {
      position: relative;
      margin: -5px;
      display: inline-block;
      padding: 5px 15px 5px 5px;
    }
    pre.change_deletion,
    pre.change_addition {
      overflow: inherit;
    }
    .change_deletion code,
    .change_addition code {
      padding: 4px 5px !important;
      margin: -4px 0 !important;
      display: inline-block !important;
    }
    .change_deletion code {
      color: #721c24;
      background-color: #f8d7da;
    }
    .change_addition code {
      color: #155724;
      background-color: #d4edda;
    }

    .change-context div {
      display: inline-block;
    }
    .change-context div.context:first-child::before {
      content: '';
    }
    .change-context div.context::before {
      content: ', ';
    }
  }
</style>