<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import type { DeeplinkTemplate, App, Environment } from '@/types'
import { useHistoryStore } from '@/stores/history'

const props = defineProps<{
  deeplink: DeeplinkTemplate
  app: App
  environment: Environment
}>()

const emit = defineEmits<{
  close: []
  edit: [deeplink: DeeplinkTemplate]
  delete: [deeplinkId: string]
}>()

const historyStore = useHistoryStore()

const selectedEnv = computed(() => props.environment)

// Extract path params from `:paramName` tokens
const pathParams = computed<string[]>(() => {
  const matches = (props.deeplink.path ?? '').match(/:[a-zA-Z]+/g) ?? []
  return matches.map(m => m.slice(1))
})

// State for path param values
const pathValues = ref<Record<string, string>>({})

// State for query param values
const queryValues = ref<Record<string, string | boolean | string[]>>({})

// Initialize states when deeplink changes
watch(
  () => props.deeplink,
  () => {
    pathValues.value = {}
    queryValues.value = {}
    for (const key of pathParams.value) {
      pathValues.value[key] = ''
    }
    for (const [key, type] of Object.entries(props.deeplink.queryParams)) {
      if (type === 'boolean') {
        queryValues.value[key] = false
      } else if (type === 'list') {
        queryValues.value[key] = ['']
      } else {
        queryValues.value[key] = ''
      }
    }
  },
  { immediate: true }
)

function addListItem(key: string) {
  const arr = queryValues.value[key] as string[]
  queryValues.value[key] = [...arr, '']
}

function removeListItem(key: string, index: number) {
  const arr = queryValues.value[key] as string[]
  queryValues.value[key] = arr.filter((_, i) => i !== index)
}

function updateListItem(key: string, index: number, val: string) {
  const arr = [...(queryValues.value[key] as string[])]
  arr[index] = val
  queryValues.value[key] = arr
}

const unfilledParams = computed(() =>
  pathParams.value.filter(p => !pathValues.value[p]?.trim())
)

// Build URI
const builtUri = computed<string>(() => {
  const env = selectedEnv.value
  if (!env) return ''

  // Normalize scheme: strip trailing :// or : if the user included it
  const scheme = env.scheme.replace(/:\/?\/?$/, '')

  // Fill path params
  let filledPath = props.deeplink.path ?? ''
  for (const [key, val] of Object.entries(pathValues.value)) {
    filledPath = filledPath.replace(`:${key}`, val.trim() || `:${key}`)
  }
  // Ensure path starts with / when non-empty
  if (filledPath && !filledPath.startsWith('/')) filledPath = `/${filledPath}`

  // Build query string
  const queryParts: string[] = []
  for (const [key, type] of Object.entries(props.deeplink.queryParams)) {
    const val = queryValues.value[key]
    if (type === 'boolean') {
      if (val === true) queryParts.push(`${encodeURIComponent(key)}=true`)
    } else if (type === 'list') {
      const arr = (val as string[]).filter(v => v.trim())
      for (const item of arr) {
        queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(item)}`)
      }
    } else {
      const str = val as string
      if (str.trim()) {
        queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(str)}`)
      }
    }
  }

  const queryString = queryParts.length > 0 ? `?${queryParts.join('&')}` : ''
  const fragment = props.deeplink.fragment ? `#${encodeURIComponent(props.deeplink.fragment)}` : ''

  return `${scheme}://${props.deeplink.host}${filledPath}${queryString}${fragment}`
})

function launch() {
  if (!selectedEnv.value) return
  const uri = builtUri.value
  window.open(uri)
  historyStore.addEntry({
    deeplinkName: props.deeplink.name,
    uri,
    environment: selectedEnv.value.name,
  })
  emit('close')
}

function copyUri() {
  navigator.clipboard.writeText(builtUri.value)
}

function onOverlayClick(e: MouseEvent) {
  if (e.target === e.currentTarget) emit('close')
}
</script>

<template>
  <div class="modal-overlay" @click="onOverlayClick">
    <div class="modal launch-modal">
      <!-- Header -->
      <div class="modal-header">
        <div>
          <div class="modal-title">{{ deeplink.name }}</div>
          <div class="modal-subtitle" v-if="deeplink.description">{{ deeplink.description }}</div>
        </div>
        <div class="modal-header-actions">
          <button class="action-btn" title="Edit deeplink" @click="emit('edit', deeplink)">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/>
              <path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/>
            </svg>
          </button>
          <button class="action-btn action-btn-danger" title="Delete deeplink" @click="emit('delete', deeplink.id)">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <polyline points="3 6 5 6 21 6"/>
              <path d="M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/>
              <path d="M10 11v6M14 11v6"/>
              <path d="M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2"/>
            </svg>
          </button>
          <button class="modal-close" @click="emit('close')">✕</button>
        </div>
      </div>

      <div class="modal-body">
        <!-- Path params -->
        <div v-if="pathParams.length > 0" class="section">
          <div class="section-label">Path Parameters</div>
          <div class="params-list">
            <div
              v-for="param in pathParams"
              :key="param"
              class="param-row"
            >
              <label class="param-label">{{ param }}</label>
              <input
                v-model="pathValues[param]"
                class="form-input"
                :placeholder="`Enter ${param}`"
              />
            </div>
          </div>
        </div>

        <!-- Query params -->
        <div
          v-if="Object.keys(deeplink.queryParams).length > 0"
          class="section"
        >
          <div class="section-label">Query Parameters</div>
          <div class="params-list">
            <template
              v-for="[key, type] in Object.entries(deeplink.queryParams)"
              :key="key"
            >
              <!-- String -->
              <div v-if="type === 'string'" class="param-row">
                <label class="param-label">
                  {{ key }}
                  <span class="param-type">string</span>
                </label>
                <input
                  v-model="(queryValues[key] as string)"
                  class="form-input"
                  :placeholder="`Enter ${key}`"
                />
              </div>

              <!-- Boolean -->
              <div v-else-if="type === 'boolean'" class="param-row param-row-bool">
                <label class="param-label">
                  {{ key }}
                  <span class="param-type">boolean</span>
                </label>
                <label class="toggle">
                  <input type="checkbox" v-model="(queryValues[key] as boolean)" />
                  <span class="toggle-slider"></span>
                </label>
              </div>

              <!-- List -->
              <div v-else-if="type === 'list'" class="param-row param-row-list">
                <label class="param-label">
                  {{ key }}
                  <span class="param-type">list</span>
                </label>
                <div class="list-items">
                  <div
                    v-for="(item, idx) in (queryValues[key] as string[])"
                    :key="idx"
                    class="list-item-row"
                  >
                    <input
                      :value="item"
                      class="form-input"
                      :placeholder="`Item ${idx + 1}`"
                      @input="updateListItem(key, idx, ($event.target as HTMLInputElement).value)"
                    />
                    <button
                      type="button"
                      class="list-remove-btn"
                      @click="removeListItem(key, idx)"
                    >
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                        <path d="M18 6L6 18M6 6l12 12"/>
                      </svg>
                    </button>
                  </div>
                  <button
                    type="button"
                    class="add-list-btn"
                    @click="addListItem(key)"
                  >
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                      <path d="M12 5v14M5 12h14"/>
                    </svg>
                    Add item
                  </button>
                </div>
              </div>
            </template>
          </div>
        </div>

        <!-- URI Preview -->
        <div class="section">
          <div class="section-label-row">
            <span class="section-label">URI Preview</span>
            <button class="copy-btn" @click="copyUri" title="Copy URI">
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
                <path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/>
              </svg>
              Copy
            </button>
          </div>
          <div class="uri-preview">{{ builtUri || '(select an environment)' }}</div>
        </div>

        <!-- Actions -->
        <div v-if="unfilledParams.length > 0" class="error-message" style="margin-bottom: 12px">
          Fill required path params: {{ unfilledParams.join(', ') }}
        </div>
        <div class="launch-actions">
          <button class="btn btn-secondary" @click="emit('close')">Cancel</button>
          <button
            class="btn btn-primary launch-btn"
            :disabled="unfilledParams.length > 0"
            @click="launch"
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
              <path d="M5 12h14M12 5l7 7-7 7"/>
            </svg>
            Launch
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.launch-modal {
  max-width: 580px;
}

.modal-subtitle {
  font-size: 13px;
  color: var(--color-text-muted);
  margin-top: 2px;
}

.modal-header-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.action-btn {
  width: 30px;
  height: 30px;
  border-radius: 6px;
  border: none;
  background: var(--color-surface-raised);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}

.action-btn:hover {
  background: var(--color-border);
  color: var(--color-text);
}

.action-btn-danger:hover {
  background: rgba(239, 68, 68, 0.1);
  color: var(--color-error);
}

.section {
  margin-bottom: 20px;
}

.section-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-bottom: 8px;
}

.section-label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.env-tabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.env-tab {
  padding: 6px 14px;
  border-radius: 6px;
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  color: var(--color-text-muted);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}

.env-tab:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.env-tab.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.params-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.param-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.param-row-bool {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.param-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--color-text);
  display: flex;
  align-items: center;
  gap: 6px;
}

.param-type {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
  background: var(--color-surface-raised);
  padding: 1px 5px;
  border-radius: 3px;
}

.param-row-list {
  flex-direction: column;
}

.list-items {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.list-item-row {
  display: flex;
  gap: 6px;
}

.list-remove-btn {
  width: 34px;
  height: 36px;
  border-radius: 6px;
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.12s, color 0.12s;
}

.list-remove-btn:hover {
  background: rgba(239, 68, 68, 0.1);
  color: var(--color-error);
}

.add-list-btn {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 6px 10px;
  border: 1px dashed var(--color-border);
  border-radius: 6px;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 12px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}

.add-list-btn:hover {
  background: var(--color-surface-raised);
  color: var(--color-primary);
  border-color: var(--color-primary);
}

.copy-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--color-text-muted);
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
  transition: background 0.12s, color 0.12s;
}

.copy-btn:hover {
  background: var(--color-surface-raised);
  color: var(--color-primary);
}

.launch-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 4px;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
}

.launch-btn {
  min-width: 110px;
  justify-content: center;
}
</style>