<template>
  <div class="external-api-panel mt-6">
    <div class="card-header">
      <div class="title-row">
        <inPipeBaseText variant="title" tag="h3">
          {{ $__("components.settings.external_api.title", "UTM API Access") }}
        </inPipeBaseText>
        <button
          class="helper-btn"
          @click.stop="openLink('https://support.seresa.io/docs/inpipe-utm-api-documentation')"
        >
          <span>?</span>
          <div class="tooltip">{{ $__("components.settings.external_api.help", "Learn how to connect external tools to your UTM API.") }}</div>
        </button>
      </div>
      <inPipeBaseText variant="description">
        {{ $__("components.settings.external_api.description", "Securely connect external tools and automations to your UTM links with a key-protected REST API.") }}
      </inPipeBaseText>
    </div>

    <!-- Master toggle -->
    <div class="setting-item">
      <div class="setting-control">
        <inPipeBaseToggle
          v-model="config.enabled"
          :disabled="isBusy"
          @update:modelValue="onToggle('enabled', $event)"
        />
        <div class="setting-info">
          <inPipeBaseText class="setting-label">
            {{ $__("components.settings.external_api.master_label", "Enable UTM API Access") }}
          </inPipeBaseText>
          <inPipeBaseText variant="description" class="setting-description">
            {{ $__("components.settings.external_api.master_description", "Choose what's allowed below.") }}
          </inPipeBaseText>
        </div>
      </div>
    </div>

    <!-- Sub-toggles (only when master is on) -->
    <div v-if="config.enabled" class="sub-toggles">
      <div class="setting-item indented">
        <div class="setting-control">
          <inPipeBaseToggle
            v-model="config.read_enabled"
            :disabled="isBusy"
            @update:modelValue="onToggle('read_enabled', $event)"
          />
          <div class="setting-info">
            <inPipeBaseText class="setting-label">
              {{ $__("components.settings.external_api.read_label", "Read API") }}
            </inPipeBaseText>
            <inPipeBaseText variant="description" class="setting-description">
              {{ $__("components.settings.external_api.read_description", "Lets you read your saved UTM links.") }}
            </inPipeBaseText>
            <div class="inline-key">
              <span class="key-label">{{ $__("components.settings.external_api.key_label", "Key:") }}</span>
              <code class="key-value">{{ config.key_ro_masked || $__("components.settings.external_api.no_key", "Not generated yet") }}</code>
              <inPipeBaseButton variant="primary" size="small" class="key-btn" :disabled="!config.key_ro"
                :title="$__('components.settings.external_api.copy', 'Copy')" :aria-label="$__('components.settings.external_api.copy', 'Copy')"
                @click="copyKey('ro')">
                <Copy :size="15" />
              </inPipeBaseButton>
              <inPipeBaseButton variant="ghost" size="small" class="key-btn" :loading="regenerating === 'ro'"
                :title="$__('components.settings.external_api.regenerate', 'Regenerate')" :aria-label="$__('components.settings.external_api.regenerate', 'Regenerate')"
                @click="regenerate('ro')">
                <RefreshCw :size="15" />
              </inPipeBaseButton>
            </div>
          </div>
        </div>
      </div>

      <div class="setting-item indented">
        <div class="setting-control">
          <inPipeBaseToggle
            v-model="config.write_enabled"
            :disabled="isBusy"
            @update:modelValue="onToggle('write_enabled', $event)"
          />
          <div class="setting-info">
            <inPipeBaseText class="setting-label">
              {{ $__("components.settings.external_api.write_label", "Update API") }}
            </inPipeBaseText>
            <inPipeBaseText variant="description" class="setting-description">
              {{ $__("components.settings.external_api.write_description", "Lets you create, edit, and delete UTM links.") }}
            </inPipeBaseText>
            <div class="inline-key">
              <span class="key-label">{{ $__("components.settings.external_api.key_label", "Key:") }}</span>
              <code class="key-value">{{ config.key_rw_masked || $__("components.settings.external_api.no_key", "Not generated yet") }}</code>
              <inPipeBaseButton variant="primary" size="small" class="key-btn" :disabled="!config.key_rw"
                :title="$__('components.settings.external_api.copy', 'Copy')" :aria-label="$__('components.settings.external_api.copy', 'Copy')"
                @click="copyKey('rw')">
                <Copy :size="15" />
              </inPipeBaseButton>
              <inPipeBaseButton variant="ghost" size="small" class="key-btn" :loading="regenerating === 'rw'"
                :title="$__('components.settings.external_api.regenerate', 'Regenerate')" :aria-label="$__('components.settings.external_api.regenerate', 'Regenerate')"
                @click="regenerate('rw')">
                <RefreshCw :size="15" />
              </inPipeBaseButton>
            </div>
          </div>
        </div>
      </div>

      <p class="key-rotation-note">
        {{ $__("components.settings.external_api.rotation_note", "For better security, regenerate your keys every few months.") }}
      </p>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from "vue";
import { useToast } from "vue-toastification";
import { $__ } from "@utils/inPipeTranslate.js";
import api from "@utils/inPipeAxios.js";
import API_ENDPOINTS from "@utils/inPipeApiEndpoints.js";

import inPipeBaseText from "@base/inPipeBaseText.vue";
import inPipeBaseToggle from "@base/inPipeBaseToggle.vue";
import inPipeBaseButton from "@base/inPipeBaseButton.vue";
import { Copy, RefreshCw } from "lucide-vue-next";

const toast = useToast();

const blankConfig = () => ({
  enabled: false,
  read_enabled: false,
  write_enabled: false,
  trust_proxy_ssl: false,
  limits: {
    read: { daily: 500, burst: 60 },
    write: { daily: 150, burst: 20 },
    delete: { daily: 30, burst: 5 },
  },
  storage_cap: 500,
  key_ro: "",
  key_rw: "",
  key_ro_masked: "",
  key_rw_masked: "",
  has_keys: false,
});

const config = reactive(blankConfig());
const isBusy = ref(false);
const regenerating = ref("");

const applyConfig = (data) => {
  Object.assign(config, blankConfig(), data || {});
};

const loadConfig = async () => {
  try {
    const { data } = await api.get(API_ENDPOINTS.EXT_SETTINGS);
    applyConfig(data);
  } catch (e) {
    toast.error($__("components.settings.external_api.load_error", "Could not load UTM API Access settings."));
  }
};

const save = async (payload) => {
  isBusy.value = true;
  try {
    const { data } = await api.post(API_ENDPOINTS.EXT_SETTINGS, payload);
    applyConfig(data);
    toast.success($__("components.settings.external_api.saved", "UTM API Access settings saved."));
  } catch (e) {
    toast.error($__("components.settings.external_api.save_error", "Could not save UTM API Access settings."));
    await loadConfig();
  } finally {
    isBusy.value = false;
  }
};

const onToggle = (field, value) => {
  save({ [field]: !!value });
};

const regenerate = async (scope) => {
  const confirmMsg = $__(
    "components.settings.external_api.regen_confirm",
    "Generating a new key turns off the current one immediately. Update any tool or automation that uses it. Continue?"
  );
  if (!window.confirm(confirmMsg)) return;
  regenerating.value = scope;
  try {
    const { data } = await api.post(API_ENDPOINTS.EXT_REGENERATE_KEY, { scope });
    config[`key_${scope}`] = data.key;
    config[`key_${scope}_masked`] = maskLocally(data.key);
    config.has_keys = true;
    toast.success($__("components.settings.external_api.regenerated", "Key regenerated."));
  } catch (e) {
    toast.error($__("components.settings.external_api.regen_error", "Could not regenerate the key."));
  } finally {
    regenerating.value = "";
  }
};

const maskLocally = (key) => {
  if (!key) return "";
  const tail = key.length > 6 ? key.slice(-6) : key;
  return "••••••••" + tail;
};

const copyKey = async (scope) => {
  const value = config[`key_${scope}`];
  if (!value) {
    toast.error($__("components.settings.external_api.copy_masked", "No key yet — enable the API to generate one."));
    return;
  }
  if (await copyToClipboard(value)) {
    toast.success($__("components.settings.external_api.copied", "Key copied to clipboard."));
  } else {
    toast.error($__("components.settings.external_api.copy_error", "Could not copy. Select the key and copy manually."));
  }
};

// Robust copy: the async Clipboard API needs a secure context (https/localhost);
// fall back to execCommand for http sites so copy still works.
const copyToClipboard = async (text) => {
  if (navigator.clipboard && window.isSecureContext) {
    try {
      await navigator.clipboard.writeText(text);
      return true;
    } catch (e) {
      /* fall through to the legacy path */
    }
  }
  try {
    const ta = document.createElement("textarea");
    ta.value = text;
    ta.setAttribute("readonly", "");
    ta.style.position = "fixed";
    ta.style.top = "-9999px";
    ta.style.opacity = "0";
    document.body.appendChild(ta);
    ta.focus();
    ta.select();
    ta.setSelectionRange(0, ta.value.length);
    const ok = document.execCommand("copy");
    document.body.removeChild(ta);
    return ok;
  } catch (e) {
    return false;
  }
};

const openLink = (url) => {
  if (url) window.open(url, "_blank", "noopener,noreferrer");
};

onMounted(loadConfig);
</script>

<style scoped>
.external-api-panel {
	border-top: 1px solid var(--inpipe-border, #e5e7eb);
	padding-top: 1.25rem;
}

.card-header {
	margin-bottom: 1rem;
}

.title-row {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

/* The title variant (.card-title) carries a 1rem bottom margin; neutralize it
   inside the row so the helper button centers on the text, not text + margin. */
.title-row :deep(.card-title) {
	margin-bottom: 0;
}

/* Helper (?) button — matches premium's health-check helper for a consistent layout. */
.helper-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	border: 1.5px solid #c0c0c0;
	background: transparent;
	cursor: pointer;
	padding: 0;
	flex-shrink: 0;
	position: relative;
	transition: border-color 0.12s;
}

.helper-btn:hover {
	border-color: #888;
}

.helper-btn span {
	font-size: 0.6875rem;
	font-weight: 700;
	color: #999;
	line-height: 1;
	display: block;
	transition: color 0.12s;
}

.helper-btn:hover span {
	color: #555;
}

.helper-btn .tooltip {
	display: none;
	position: absolute;
	bottom: calc(100% + 8px);
	left: 50%;
	transform: translateX(-50%);
	background: var(--color-slate, #1e1e2f);
	color: #fff;
	font-size: 0.75rem;
	font-weight: 400;
	padding: 0.375rem 0.625rem;
	border-radius: 5px;
	max-width: 260px;
	white-space: normal;
	z-index: 10;
	pointer-events: none;
}

.helper-btn .tooltip::after {
	content: "";
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	border: 4px solid transparent;
	border-top-color: var(--color-slate, #1e1e2f);
}

.helper-btn:hover .tooltip {
	display: block;
}

.setting-item {
	padding: 0.75rem 0;
}

.setting-item.indented {
	padding: 0.75rem 0 0.75rem 1.5rem;
}

.setting-control {
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
}

.setting-info {
	display: flex;
	flex-direction: column;
}

.setting-label {
	font-weight: 600;
}

/* Nested look via indent + accent border; sub-toggles slightly smaller than the master. */
.sub-toggles {
	margin-left: 0.5rem;
}

.sub-toggles .setting-control {
	align-items: flex-start;
	gap: 0.5rem;
}

.sub-toggles :deep(.toggle-container) {
	transform: scale(0.82);
	transform-origin: left center;
	margin-right: -0.3rem;
}

/* Key row sits inside the text column, under the description. */
.inline-key {
	display: flex;
	align-items: center;
	gap: 0.3rem;
	margin-top: 0.35rem;
	flex-wrap: wrap;
}

.key-label {
	font-size: 0.72rem;
	font-weight: 600;
	color: var(--inpipe-text-muted, #4b5563);
}

.key-value {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.72rem;
	background: var(--inpipe-code-bg, #f3f4f6);
	padding: 0.12rem 0.4rem;
	border-radius: 4px;
	word-break: break-all;
	color: var(--inpipe-text-muted, #4b5563);
	margin-right: 0.2rem;
}

/* Icon-only base buttons in the key row (base `size-small` has no CSS of its own). */
.inline-key :deep(.key-btn) {
	padding: 0.35rem;
	line-height: 0;
}

.inline-key :deep(.key-btn .button-text) {
	display: inline-flex;
	line-height: 0;
}

.key-rotation-note {
	margin: 0.9rem 0 0;
	padding-left: 0.1rem;
	font-size: 0.72rem;
	color: var(--inpipe-text-muted, #6b7280);
}
</style>
