<script setup lang="ts">
import { ref, onMounted } from "vue";
import { Icon } from "@iconify/vue";

interface ApiToken {
  id: string;
  name: string;
  lastUsedAt: string | null;
  createdAt: string;
}

const props = defineProps<{
  initialTokens: ApiToken[];
}>();

const tokens = ref<ApiToken[]>(props.initialTokens);
const createModalOpen = ref(false);
const showTokenModalOpen = ref(false);
const newTokenName = ref("");
const newTokenValue = ref("");
const loading = ref(false);
const isMounted = ref(false);

onMounted(() => {
  isMounted.value = true;
});

function formatDate(dateString: string | null) {
  if (!dateString) return "Never";
  return new Date(dateString).toLocaleDateString();
}

async function createToken() {
  if (!newTokenName.value) return;

  loading.value = true;
  try {
    const response = await fetch("/api/user/tokens", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ name: newTokenName.value }),
    });

    if (response.ok) {
      const data = await response.json();

      const { token, ...tokenMeta } = data;

      tokens.value.unshift({
        id: tokenMeta.id,
        name: tokenMeta.name,
        lastUsedAt: tokenMeta.lastUsedAt,
        createdAt: tokenMeta.createdAt,
      });

      newTokenValue.value = token;
      createModalOpen.value = false;
      showTokenModalOpen.value = true;
      newTokenName.value = "";
    } else {
      alert("Failed to create token");
    }
  } catch (error) {
    console.error("Error creating token:", error);
    alert("An error occurred");
  } finally {
    loading.value = false;
  }
}

async function deleteToken(id: string) {
  if (
    !confirm(
      "Are you sure you want to revoke this token? Any applications using it will stop working.",
    )
  ) {
    return;
  }

  try {
    const response = await fetch(`/api/user/tokens/${id}`, {
      method: "DELETE",
    });

    if (response.ok) {
      tokens.value = tokens.value.filter((t) => t.id !== id);
    } else {
      alert("Failed to delete token");
    }
  } catch (error) {
    console.error("Error deleting token:", error);
    alert("An error occurred");
  }
}

function copyToken() {
  navigator.clipboard.writeText(newTokenValue.value);
}

function closeShowTokenModal() {
  showTokenModalOpen.value = false;
  newTokenValue.value = "";
}
</script>

<template>
  <div>
    <div class="card bg-base-100 shadow-xl border border-base-200 mb-6">
      <div class="card-body p-4 sm:p-6">
        <div class="flex justify-between items-center mb-6">
          <h2 class="card-title text-lg sm:text-xl">
            <Icon
              icon="heroicons:code-bracket-square"
              class="w-5 h-5 sm:w-6 sm:h-6"
            />
            API Tokens
          </h2>
          <button
            class="btn btn-primary btn-sm"
            @click="createModalOpen = true"
          >
            <Icon icon="heroicons:plus" class="w-4 h-4" />
            Create Token
          </button>
        </div>

        <div class="overflow-x-auto">
          <table class="table">
            <thead>
              <tr>
                <th>Name</th>
                <th>Last Used</th>
                <th>Created</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              <tr v-if="tokens.length === 0">
                <td colspan="4" class="text-center text-base-content/60 py-4">
                  No API tokens found. Create one to access the API.
                </td>
              </tr>
              <tr v-else v-for="token in tokens" :key="token.id">
                <td class="font-medium">{{ token.name }}</td>
                <td class="text-sm">
                  <span v-if="isMounted">{{
                    formatDate(token.lastUsedAt)
                  }}</span>
                  <span v-else>{{ token.lastUsedAt || "Never" }}</span>
                </td>
                <td class="text-sm">
                  <span v-if="isMounted">{{
                    formatDate(token.createdAt)
                  }}</span>
                  <span v-else>{{ token.createdAt }}</span>
                </td>
                <td>
                  <button
                    class="btn btn-ghost btn-xs text-error"
                    @click="deleteToken(token.id)"
                  >
                    <Icon icon="heroicons:trash" class="w-4 h-4" />
                  </button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>

    <!-- Create Token Modal -->
    <dialog class="modal" :class="{ 'modal-open': createModalOpen }">
      <div class="modal-box">
        <h3 class="font-bold text-lg">Create API Token</h3>
        <p class="py-4 text-sm text-base-content/70">
          API tokens allow you to authenticate with the API programmatically.
          Give your token a descriptive name.
        </p>

        <form @submit.prevent="createToken" class="space-y-4">
          <div class="form-control">
            <label class="label pb-2 font-medium" for="token-name">
              Token Name
            </label>
            <input
              type="text"
              id="token-name"
              v-model="newTokenName"
              placeholder="e.g. CI/CD Pipeline"
              class="input input-bordered w-full"
              required
            />
          </div>

          <div class="modal-action">
            <button type="button" class="btn" @click="createModalOpen = false">
              Cancel
            </button>
            <button type="submit" class="btn btn-primary" :disabled="loading">
              <span
                v-if="loading"
                class="loading loading-spinner loading-sm"
              ></span>
              Generate Token
            </button>
          </div>
        </form>
      </div>
      <form
        method="dialog"
        class="modal-backdrop"
        @click="createModalOpen = false"
      >
        <button>close</button>
      </form>
    </dialog>

    <!-- Show Token Modal -->
    <dialog class="modal" :class="{ 'modal-open': showTokenModalOpen }">
      <div class="modal-box">
        <h3 class="font-bold text-lg text-success flex items-center gap-2">
          <Icon icon="heroicons:check-circle" class="w-6 h-6" />
          Token Created
        </h3>
        <p class="py-4">
          Make sure to copy your personal access token now. You won't be able to
          see it again!
        </p>

        <div
          class="bg-base-200 p-4 rounded-lg break-all font-mono text-sm relative group"
        >
          <span>{{ newTokenValue }}</span>
          <button
            class="absolute top-2 right-2 btn btn-xs btn-ghost opacity-0 group-hover:opacity-100 transition-opacity"
            @click="copyToken"
            title="Copy to clipboard"
          >
            <Icon icon="heroicons:clipboard" class="w-4 h-4" />
          </button>
        </div>

        <div class="modal-action">
          <button class="btn btn-primary" @click="closeShowTokenModal">
            Done
          </button>
        </div>
      </div>
      <form method="dialog" class="modal-backdrop" @click="closeShowTokenModal">
        <button>close</button>
      </form>
    </dialog>
  </div>
</template>
