<script lang="ts">
  import { locale } from '$lib/stores/preferences.store';
  import { createApiKey, deleteApiKey, getApiKeys, updateApiKey, type ApiKeyResponseDto } from '@immich/sdk';
  import { mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
  import { fade } from 'svelte/transition';
  import { handleError } from '../../utils/handle-error';
  import Button from '../elements/buttons/button.svelte';
  import APIKeyForm from '../forms/api-key-form.svelte';
  import APIKeySecret from '../forms/api-key-secret.svelte';
  import ConfirmDialogue from '../shared-components/confirm-dialogue.svelte';
  import { NotificationType, notificationController } from '../shared-components/notification/notification';
  import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';

  export let keys: ApiKeyResponseDto[];

  let newKey: Partial<ApiKeyResponseDto> | null = null;
  let editKey: ApiKeyResponseDto | null = null;
  let deleteKey: ApiKeyResponseDto | null = null;
  let secret = '';

  const format: Intl.DateTimeFormatOptions = {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  };

  async function refreshKeys() {
    keys = await getApiKeys();
  }

  const handleCreate = async (detail: Partial<ApiKeyResponseDto>) => {
    try {
      const data = await createApiKey({ apiKeyCreateDto: detail });
      secret = data.secret;
    } catch (error) {
      handleError(error, 'Unable to create a new API Key');
    } finally {
      await refreshKeys();
      newKey = null;
    }
  };

  const handleUpdate = async (detail: Partial<ApiKeyResponseDto>) => {
    if (!editKey || !detail.name) {
      return;
    }

    try {
      await updateApiKey({ id: editKey.id, apiKeyUpdateDto: { name: detail.name } });
      notificationController.show({
        message: `Saved API Key`,
        type: NotificationType.Info,
      });
    } catch (error) {
      handleError(error, 'Unable to save API Key');
    } finally {
      await refreshKeys();
      editKey = null;
    }
  };

  const handleDelete = async () => {
    if (!deleteKey) {
      return;
    }

    try {
      await deleteApiKey({ id: deleteKey.id });
      notificationController.show({
        message: `Removed API Key: ${deleteKey.name}`,
        type: NotificationType.Info,
      });
    } catch (error) {
      handleError(error, 'Unable to remove API Key');
    } finally {
      await refreshKeys();
      deleteKey = null;
    }
  };
</script>

{#if newKey}
  <APIKeyForm
    title="New API key"
    submitText="Create"
    apiKey={newKey}
    on:submit={({ detail }) => handleCreate(detail)}
    on:cancel={() => (newKey = null)}
  />
{/if}

{#if secret}
  <APIKeySecret {secret} on:done={() => (secret = '')} />
{/if}

{#if editKey}
  <APIKeyForm
    title="API key"
    submitText="Save"
    apiKey={editKey}
    on:submit={({ detail }) => handleUpdate(detail)}
    on:cancel={() => (editKey = null)}
  />
{/if}

{#if deleteKey}
  <ConfirmDialogue
    id="confirm-api-key-delete-modal"
    prompt="Are you sure you want to delete this API key?"
    onConfirm={() => handleDelete()}
    onClose={() => (deleteKey = null)}
  />
{/if}

<section class="my-4">
  <div class="flex flex-col gap-2" in:fade={{ duration: 500 }}>
    <div class="mb-2 flex justify-end">
      <Button size="sm" on:click={() => (newKey = { name: 'API Key' })}>New API Key</Button>
    </div>

    {#if keys.length > 0}
      <table class="w-full text-left">
        <thead
          class="mb-4 flex h-12 w-full rounded-md border bg-gray-50 text-immich-primary dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-primary"
        >
          <tr class="flex w-full place-items-center">
            <th class="w-1/3 text-center text-sm font-medium">Name</th>
            <th class="w-1/3 text-center text-sm font-medium">Created</th>
            <th class="w-1/3 text-center text-sm font-medium">Action</th>
          </tr>
        </thead>
        <tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
          {#each keys as key, index}
            {#key key.id}
              <tr
                class={`flex h-[80px] w-full place-items-center text-center dark:text-immich-dark-fg ${
                  index % 2 == 0
                    ? 'bg-immich-gray dark:bg-immich-dark-gray/75'
                    : 'bg-immich-bg dark:bg-immich-dark-gray/50'
                }`}
              >
                <td class="w-1/3 text-ellipsis px-4 text-sm">{key.name}</td>
                <td class="w-1/3 text-ellipsis px-4 text-sm"
                  >{new Date(key.createdAt).toLocaleDateString($locale, format)}
                </td>
                <td class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-1/3">
                  <CircleIconButton
                    color="primary"
                    icon={mdiPencilOutline}
                    title="Edit key"
                    size="16"
                    on:click={() => (editKey = key)}
                  />
                  <CircleIconButton
                    color="primary"
                    icon={mdiTrashCanOutline}
                    title="Delete key"
                    size="16"
                    on:click={() => (deleteKey = key)}
                  />
                </td>
              </tr>
            {/key}
          {/each}
        </tbody>
      </table>
    {/if}
  </div>
</section>
