<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { VaultServer, VaultCredentials } from "../types";
import { vaultApi, VaultError } from "../services/vaultApi";

interface Props {
  server: VaultServer;
  credentials: VaultCredentials;
  secretPath: string;
}

const props = defineProps<Props>();
const emit = defineEmits<{
  close: [];
}>();

const secretData = ref<Record<string, unknown> | null>(null);
const secretMetadata = ref<any>(null);
const secretVersions = ref<any[]>([]);
const isLoading = ref(false);
const error = ref<string | null>(null);
const activeTab = ref<"current" | "json" | "metadata" | "versions">("current");
const visibleValues = ref<Record<string, boolean>>({});

onMounted(() => {
  loadSecret();
});

const loadSecret = async () => {
  isLoading.value = true;
  error.value = null;

  try {
    // Load current secret data
    const response = await vaultApi.readSecret(
      props.server,
      props.credentials,
      props.secretPath,
    );

    console.log("Secret response structure:", response);

    // For KV v2, the response includes both data and metadata
    if (response && typeof response === "object") {
      // Extract secret data (usually under 'data' key)
      secretData.value = response.data || response;

      // Extract metadata if present in the response
      if (response.metadata) {
        secretMetadata.value = {
          ...response.metadata,
          // Add any additional metadata fields from the response root
          current_version: response.metadata.version,
          created_time: response.metadata.created_time,
          updated_time: response.metadata.created_time, // KV v2 doesn't have separate updated_time in single secret response
          destroyed: response.metadata.destroyed,
          deletion_time: response.metadata.deletion_time,
          custom_metadata: response.metadata.custom_metadata,
        };

        // Create a single version entry from the current metadata
        if (response.metadata.version) {
          secretVersions.value = [
            {
              version: response.metadata.version,
              created_time: new Date(
                response.metadata.created_time,
              ).toLocaleString(),
              destroyed: response.metadata.destroyed,
              deletion_time: response.metadata.deletion_time,
            },
          ];
        }
      }
    } else {
      secretData.value = response;
    }

    // Try to load full metadata and version history from metadata endpoint
    await loadMetadataAndVersions();
  } catch (err) {
    console.error("Error loading secret:", err);
    if (err instanceof VaultError) {
      error.value = `${err.message} (HTTP ${err.statusCode || "Unknown"})`;
      if (err.errors && err.errors.length > 0) {
        error.value += `\n\nDetails:\n${err.errors.join("\n")}`;
      }
    } else {
      error.value = err instanceof Error ? err.message : "Unknown error";
    }
  } finally {
    isLoading.value = false;
  }
};

const loadMetadataAndVersions = async () => {
  try {
    // Use the dedicated readSecretMetadata method from VaultApi
    const fullMetadata = await vaultApi.readSecretMetadata(
      props.server,
      props.credentials,
      props.secretPath,
    );

    if (fullMetadata) {
      console.log("Full metadata response:", fullMetadata);

      // Merge with existing metadata or replace it
      secretMetadata.value = {
        ...secretMetadata.value, // Keep any metadata from the secret response
        ...fullMetadata, // Override with full metadata
      };

      // Extract complete version history from full metadata
      if (fullMetadata.versions) {
        secretVersions.value = Object.entries(fullMetadata.versions)
          .map(([version, versionData]: [string, any]) => ({
            version: parseInt(version),
            ...versionData,
            created_time: new Date(versionData.created_time).toLocaleString(),
          }))
          .sort((a, b) => b.version - a.version); // Latest first
      } else if (secretMetadata.value?.current_version) {
        // Fallback: if no versions array but we have current version info
        secretVersions.value = [
          {
            version: secretMetadata.value.current_version,
            created_time: secretMetadata.value.created_time
              ? new Date(secretMetadata.value.created_time).toLocaleString()
              : "Unknown",
            destroyed: secretMetadata.value.destroyed || false,
            deletion_time: secretMetadata.value.deletion_time,
          },
        ];
      }
    }
  } catch (err) {
    console.warn(
      "Could not load full metadata (using basic metadata from secret response):",
      err,
    );
    // If we can't load full metadata, we'll use what we extracted from the secret response
  }
};

const loadVersion = async (version: number) => {
  isLoading.value = true;
  error.value = null;

  try {
    // For KV v2, append ?version=X to get specific version
    const versionPath = `${props.secretPath}?version=${version}`;
    const data = await vaultApi.readSecret(
      props.server,
      props.credentials,
      versionPath,
    );
    secretData.value = data;
    activeTab.value = "current";
  } catch (err) {
    console.error("Error loading version:", err);
    error.value = err instanceof Error ? err.message : "Unknown error";
  } finally {
    isLoading.value = false;
  }
};

const formatBytes = (bytes: number): string => {
  if (bytes === 0) return "0 Bytes";
  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + " " + sizes[i];
};

const copyToClipboard = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text);
    // Could add a toast notification here
  } catch (err) {
    console.error("Failed to copy:", err);
  }
};

const toggleValueVisibility = (key: string) => {
  visibleValues.value[key] = !visibleValues.value[key];
};

const isValueVisible = (key: string): boolean => {
  return visibleValues.value[key] || false;
};

const maskValue = (value: string): string => {
  return "•".repeat(Math.min(value.length, 12));
};

const getDisplayValue = (key: string, value: unknown): string => {
  const stringValue = typeof value === "string" ? value : JSON.stringify(value);
  return isValueVisible(key) ? stringValue : maskValue(stringValue);
};

const toggleAllValues = () => {
  if (!secretData.value) return;

  // Check if any values are currently visible
  const hasVisibleValues = Object.values(visibleValues.value).some((v) => v);

  // Set all keys to the opposite state
  Object.keys(secretData.value).forEach((key) => {
    visibleValues.value[key] = !hasVisibleValues;
  });
};
</script>

<template>
  <!-- Modal Overlay -->
  <div class="modal modal-open" @click.self="emit('close')">
    <div class="modal-box max-w-6xl max-h-[90vh] overflow-hidden flex flex-col">
      <!-- Header -->
      <div class="flex justify-between items-start mb-4 flex-shrink-0">
        <div class="flex-1 min-w-0">
          <h2 class="text-xl font-bold truncate">🔐 Secret Viewer</h2>
          <p class="text-sm font-mono opacity-70 truncate mt-1">
            {{ secretPath }}
          </p>
        </div>
        <button
          class="btn btn-sm btn-circle btn-ghost ml-4"
          @click="emit('close')"
        >
          ✕
        </button>
      </div>

      <!-- Loading State -->
      <div v-if="isLoading" class="flex-1 flex items-center justify-center">
        <div class="text-center">
          <span class="loading loading-spinner loading-lg"></span>
          <p class="mt-4">Loading secret...</p>
        </div>
      </div>

      <!-- Error State -->
      <div v-else-if="error" class="flex-1">
        <div class="alert alert-error">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            class="stroke-current shrink-0 h-6 w-6"
            fill="none"
            viewBox="0 0 24 24"
          >
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
            />
          </svg>
          <div>
            <h3 class="font-bold">Failed to load secret</h3>
            <pre class="text-xs mt-2 whitespace-pre-wrap">{{ error }}</pre>
          </div>
        </div>
      </div>

      <!-- Content -->
      <div v-else class="flex-1 flex flex-col overflow-hidden">
        <!-- Tabs -->
        <div class="tabs tabs-bordered mb-4 flex-shrink-0">
          <button
            class="tab"
            :class="{ 'tab-active': activeTab === 'current' }"
            @click="activeTab = 'current'"
          >
            📄 Current Data
          </button>
          <button
            class="tab"
            :class="{ 'tab-active': activeTab === 'json' }"
            @click="activeTab = 'json'"
          >
            📋 JSON Data
          </button>
          <button
            v-if="secretMetadata"
            class="tab"
            :class="{ 'tab-active': activeTab === 'metadata' }"
            @click="activeTab = 'metadata'"
          >
            ℹ️ Metadata
          </button>
          <button
            v-if="secretVersions.length > 0"
            class="tab"
            :class="{ 'tab-active': activeTab === 'versions' }"
            @click="activeTab = 'versions'"
          >
            🕒 Versions ({{ secretVersions.length }})
          </button>
        </div>

        <!-- Tab Content -->
        <div class="flex-1 overflow-hidden">
          <!-- Current Data Tab (Table View) -->
          <div v-if="activeTab === 'current'" class="h-full flex flex-col">
            <div class="flex justify-between items-center mb-3 flex-shrink-0">
              <h3 class="font-semibold">Secret Data</h3>
              <div class="flex gap-2">
                <button class="btn btn-sm btn-outline" @click="toggleAllValues">
                  {{
                    Object.values(visibleValues).some((v) => v)
                      ? "🙈 Hide All"
                      : "👁️ Show All"
                  }}
                </button>
              </div>
            </div>
            <div class="flex-1 overflow-auto">
              <div
                v-if="secretData && Object.keys(secretData).length > 0"
                class="overflow-x-auto"
              >
                <table class="table table-zebra w-full">
                  <thead>
                    <tr>
                      <th class="w-1/3">Key</th>
                      <th class="w-1/2">Value</th>
                      <th class="w-1/6">Actions</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr
                      v-for="[key, value] in Object.entries(secretData)"
                      :key="key"
                    >
                      <td class="font-mono font-semibold">{{ key }}</td>
                      <td class="font-mono text-sm">
                        <span class="select-all">{{
                          getDisplayValue(key, value)
                        }}</span>
                      </td>
                      <td>
                        <div class="flex gap-1">
                          <button
                            class="btn btn-xs btn-ghost"
                            :title="
                              isValueVisible(key) ? 'Hide value' : 'Show value'
                            "
                            @click="toggleValueVisibility(key)"
                          >
                            {{ isValueVisible(key) ? "🙈" : "👁️" }}
                          </button>
                          <button
                            class="btn btn-xs btn-ghost"
                            title="Copy value"
                            @click="
                              copyToClipboard(
                                typeof value === 'string'
                                  ? value
                                  : JSON.stringify(value),
                              )
                            "
                          >
                            📋
                          </button>
                        </div>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <div
                v-else
                class="flex items-center justify-center h-full text-base-content/60"
              >
                <p>No secret data available</p>
              </div>
            </div>
          </div>

          <!-- JSON Data Tab -->
          <div v-else-if="activeTab === 'json'" class="h-full flex flex-col">
            <div class="flex justify-between items-center mb-3 flex-shrink-0">
              <h3 class="font-semibold">JSON Data</h3>
              <button
                class="btn btn-sm btn-outline"
                @click="copyToClipboard(JSON.stringify(secretData, null, 2))"
              >
                📋 Copy JSON
              </button>
            </div>
            <div class="flex-1 overflow-auto">
              <pre
                class="bg-base-300 p-4 rounded-lg text-sm h-full overflow-auto"
                >{{ JSON.stringify(secretData, null, 2) }}</pre
              >
            </div>
          </div>

          <!-- Metadata Tab -->
          <div
            v-else-if="activeTab === 'metadata' && secretMetadata"
            class="h-full flex flex-col"
          >
            <h3 class="font-semibold mb-3 flex-shrink-0">Secret Metadata</h3>
            <div class="flex-1 overflow-auto">
              <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
                <div class="card bg-base-200">
                  <div class="card-body p-4">
                    <h4 class="font-semibold text-sm">General Info</h4>
                    <div class="space-y-2 text-sm">
                      <div>
                        <strong>Current Version:</strong>
                        {{ secretMetadata.current_version || "N/A" }}
                      </div>
                      <div>
                        <strong>Max Versions:</strong>
                        {{ secretMetadata.max_versions || "N/A" }}
                      </div>
                      <div>
                        <strong>Oldest Version:</strong>
                        {{ secretMetadata.oldest_version || "N/A" }}
                      </div>
                      <div>
                        <strong>Created:</strong>
                        {{
                          secretMetadata.created_time
                            ? new Date(
                                secretMetadata.created_time,
                              ).toLocaleString()
                            : "N/A"
                        }}
                      </div>
                      <div>
                        <strong>Updated:</strong>
                        {{
                          secretMetadata.updated_time
                            ? new Date(
                                secretMetadata.updated_time,
                              ).toLocaleString()
                            : "N/A"
                        }}
                      </div>
                    </div>
                  </div>
                </div>

                <div class="card bg-base-200">
                  <div class="card-body p-4">
                    <h4 class="font-semibold text-sm">Status</h4>
                    <div class="space-y-2 text-sm">
                      <div>
                        <strong>Destroyed:</strong>
                        {{ secretMetadata.destroyed ? "Yes" : "No" }}
                      </div>
                      <div>
                        <strong>Delete Version After:</strong>
                        {{ secretMetadata.delete_version_after || "Never" }}
                      </div>
                      <div v-if="secretMetadata.custom_metadata">
                        <strong>Custom Metadata:</strong>
                        <pre class="text-xs mt-1 bg-base-300 p-2 rounded">{{
                          JSON.stringify(
                            secretMetadata.custom_metadata,
                            null,
                            2,
                          )
                        }}</pre>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <div class="card bg-base-200">
                <div class="card-body p-4">
                  <h4 class="font-semibold text-sm mb-2">Raw Metadata</h4>
                  <pre class="bg-base-300 p-4 rounded text-xs overflow-auto">{{
                    JSON.stringify(secretMetadata, null, 2)
                  }}</pre>
                </div>
              </div>
            </div>
          </div>

          <!-- Versions Tab -->
          <div
            v-else-if="activeTab === 'versions'"
            class="h-full flex flex-col"
          >
            <h3 class="font-semibold mb-3 flex-shrink-0">Version History</h3>
            <div class="flex-1 overflow-auto">
              <div class="space-y-2">
                <div
                  v-for="version in secretVersions"
                  :key="version.version"
                  class="card bg-base-200 hover:bg-base-300 transition-colors"
                >
                  <div
                    class="card-body p-4 flex flex-row items-center justify-between"
                  >
                    <div class="flex-1">
                      <div class="flex items-center gap-2 mb-1">
                        <span class="badge badge-primary"
                          >v{{ version.version }}</span
                        >
                        <span
                          v-if="
                            version.version === secretMetadata?.current_version
                          "
                          class="badge badge-success"
                          >Current</span
                        >
                        <span v-if="version.destroyed" class="badge badge-error"
                          >Destroyed</span
                        >
                      </div>
                      <p class="text-sm opacity-70">
                        Created: {{ version.created_time }}
                      </p>
                      <p
                        v-if="version.deletion_time"
                        class="text-sm opacity-70"
                      >
                        Deleted:
                        {{ new Date(version.deletion_time).toLocaleString() }}
                      </p>
                    </div>
                    <button
                      v-if="!version.destroyed"
                      class="btn btn-sm btn-primary"
                      @click="loadVersion(version.version)"
                    >
                      View Version
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Footer -->
      <div class="modal-action flex-shrink-0">
        <div class="flex-1 text-xs opacity-70">
          <p>🔒 Secret data is never cached - always fetched fresh</p>
          <p>📊 KV v2: Metadata and version history available</p>
        </div>
        <button class="btn" @click="emit('close')">Close</button>
      </div>
    </div>
  </div>
</template>
