<script setup>
import { ref, watch, onUnmounted } from 'vue'
import { Copy, Trash2, ExternalLink, Power, Zap, X, Settings, Download } from 'lucide-vue-next'
import { useExtension } from '../../composables/useExtension'
import { useLocalStorage } from '../../composables/useLocalStorage'
import ExtensionStatus from './common/ExtensionStatus.vue'
import UrlCleanerExceptionsModal from './UrlCleanerExceptionsModal.vue'

// Extension integration
const { isExtensionReady, isListening, lastClipboardText, startListening, stopListening, writeClipboard } = useExtension()

const inputUrl = ref('')
// Use local storage for history persistence
const cleanedHistory = useLocalStorage('url-cleaner-history', [])
const isWatchEnabled = useLocalStorage('url-cleaner-watch-enabled', false)

// Exceptions management
const showExceptionsModal = ref(false)
const defaultExceptions = [
  { id: 'yt', domainPattern: '*.youtube.com', keepParams: ['v', 't'], keepHash: false, keepAllParams: false, isEnabled: true, isDefault: true },
  { id: 'yt-short', domainPattern: 'youtu.be', keepParams: ['t'], keepHash: false, keepAllParams: false, isEnabled: true, isDefault: true }
]
const exceptions = useLocalStorage('url-cleaner-exceptions', defaultExceptions)

// Helper to match domain with glob pattern
const matchDomain = (pattern, domain) => {
  // Escape regex chars except *
  const regexString = '^' + pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$'
  return new RegExp(regexString, 'i').test(domain)
}

// Watch for clipboard changes from extension
watch(lastClipboardText, (newText) => {
  if (isWatchEnabled.value && newText) {
    processUrl(newText, true)
  }
})

// Sync watch state with extension listener
watch(isWatchEnabled, (enabled) => {
  if (enabled) {
    startListening()
  } else {
    stopListening()
  }
}, { immediate: true })

// Re-enable listening when extension becomes ready
watch(isExtensionReady, (ready) => {
  if (ready && isWatchEnabled.value) {
    startListening()
  }
})

// Toggle watch mode
const toggleWatch = () => {
  isWatchEnabled.value = !isWatchEnabled.value
}

const copyAllUrls = async () => {
  if (cleanedHistory.value.length === 0) return
  const text = cleanedHistory.value.map(item => item.cleaned).join('\n')
  try {
    await navigator.clipboard.writeText(text)
  } catch (err) {
    console.error('Failed to copy URLs', err)
  }
}

const downloadJson = () => {
  if (cleanedHistory.value.length === 0) return

  const exportData = cleanedHistory.value.map(item => ({
    url: item.cleaned,
    original: item.original,
    timestamp: item.timestamp
  }))

  const data = JSON.stringify(exportData, null, 2)
  const blob = new Blob([data], { type: 'application/json' })
  const url = URL.createObjectURL(blob)

  const a = document.createElement('a')
  a.href = url
  a.download = `cleaned-urls-${new Date().toISOString().slice(0, 10)}.json`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

// Manual clean
const handleClean = () => {
  if (inputUrl.value) {
    const urls = inputUrl.value.split(/\r?\n/).filter(line => line.trim().length > 0)
    urls.forEach(url => {
      processUrl(url.trim(), false)
    })
    inputUrl.value = ''
  }
}

const processUrl = (text, autoClipboard = false) => {
  try {
    // Basic URL validation
    if (!text.match(/^https?:\/\//i)) {
      // Not a URL, ignore in watch mode
      if (autoClipboard) return
    }

    const originalLength = text.length
    let cleanedUrl = text

    try {
      const urlObj = new URL(text)
      const hostname = urlObj.hostname

      // Check for exceptions
      const matchedRule = exceptions.value.find(rule =>
        rule.isEnabled && matchDomain(rule.domainPattern, hostname)
      )

      if (matchedRule) {
        if (!matchedRule.keepAllParams) {
          // Exception logic: keep specific params
          const params = new URLSearchParams(urlObj.search)
          const keys = Array.from(params.keys())

          for (const key of keys) {
            if (!matchedRule.keepParams.includes(key)) {
              params.delete(key)
            }
          }

          urlObj.search = params.toString()
        }

        if (!matchedRule.keepHash) {
          urlObj.hash = ''
        }
      } else {
        // Default behavior: remove all query params and hash
        if (urlObj.search || urlObj.hash) {
          urlObj.search = ''
          urlObj.hash = ''
        }
      }

      cleanedUrl = urlObj.toString()
      // Remove trailing slash if it wasn't there before? usually keep it standard
    } catch (e) {
      // Invalid URL format
      if (!autoClipboard) {
        // Show error or just return original
      }
      return
    }

    // If no change, ignore in watch mode to avoid loops
    if (cleanedUrl === text && autoClipboard) {
      return
    }

    const newLength = cleanedUrl.length
    const savedChars = originalLength - newLength
    const savedPercent = originalLength > 0 ? Math.round((savedChars / originalLength) * 100) : 0

    // Add to history
    const entry = {
      id: Date.now(),
      original: text,
      cleaned: cleanedUrl,
      savedPercent,
      timestamp: new Date().toLocaleTimeString()
    }

    cleanedHistory.value.unshift(entry)

    // Limit history
    if (cleanedHistory.value.length > 50) {
      cleanedHistory.value.pop()
    }

    // Auto-copy back to clipboard if in watch mode
    if (autoClipboard && savedChars > 0) {
      writeClipboard(cleanedUrl)
    }
  } catch (e) {
    console.error('Error processing URL:', e)
  }
}

const copyToClipboard = (text) => {
  navigator.clipboard.writeText(text)
}

const removeEntry = (id) => {
  cleanedHistory.value = cleanedHistory.value.filter(item => item.id !== id)
}

const clearHistory = () => {
  cleanedHistory.value = []
}

onUnmounted(() => {
  if (isListening.value) {
    stopListening()
  }
})
</script>

<template>
  <div class="tool-container full-width">
    <div class="tool-panel">
      <div class="panel-header">
        <h2 class="tool-title">URL Cleaner</h2>
        <div class="header-actions">
          <button class="icon-btn settings-btn" @click="showExceptionsModal = true" title="Cleaning Exceptions">
            <Settings size="20" />
          </button>
          <ExtensionStatus :isReady="isExtensionReady" />
        </div>
      </div>

      <div class="input-section">
        <div class="input-wrapper">
          <textarea
            v-model="inputUrl"
            placeholder="Paste URL(s) here to clean..."
            class="url-input"
            @keydown.enter.prevent="handleClean"
            rows="1"
          ></textarea>
          <button class="btn-neon" @click="handleClean">
            Clean
          </button>
        </div>

        <div class="watch-toggle">
          <button
            class="btn-neon toggle-btn"
            :class="{ 'active': isWatchEnabled && isExtensionReady }"
            @click="toggleWatch"
            :disabled="!isExtensionReady"
            :title="!isExtensionReady ? 'Extension required for auto-watch' : 'Automatically clean URLs from clipboard'"
          >
            <Power size="18" />
            <span>Watch Clipboard</span>
            <span v-if="isWatchEnabled && isExtensionReady" class="status-dot"></span>
          </button>
        </div>
      </div>

      <div class="history-section" v-if="cleanedHistory.length > 0">
        <div class="history-header">
          <h3>Cleaned URLs</h3>
          <div class="history-actions">
            <button class="icon-btn" @click="copyAllUrls" title="Copy all URLs">
              <Copy size="18" />
            </button>
            <button class="icon-btn" @click="downloadJson" title="Download JSON">
              <Download size="18" />
            </button>
            <button class="icon-btn delete-btn" @click="clearHistory" title="Clear History">
              <Trash2 size="18" />
            </button>
          </div>
        </div>

        <div class="history-list">
          <div v-for="item in cleanedHistory" :key="item.id" class="history-item">
            <div class="item-info">
              <div class="cleaned-url">{{ item.cleaned }}</div>
              <div class="meta-info">
                <span class="timestamp">{{ item.timestamp }}</span>
                <span class="savings" v-if="item.savedPercent > 0">
                  <Zap size="12" /> -{{ item.savedPercent }}% junk removed
                </span>
                <span class="no-change" v-else>No junk found</span>
              </div>
            </div>
            <div class="item-actions">
              <button class="icon-btn" @click="copyToClipboard(item.cleaned)" title="Copy">
                <Copy size="18" />
              </button>
              <a :href="item.cleaned" target="_blank" class="icon-btn" title="Open">
                <ExternalLink size="18" />
              </a>
              <button class="icon-btn delete-btn" @click="removeEntry(item.id)" title="Remove">
                <X size="18" />
              </button>
            </div>
          </div>
        </div>
      </div>

      <div class="empty-state" v-else>
        <p>Paste a URL above or enable "Watch Clipboard" to automatically clean links.</p>
      </div>

      <UrlCleanerExceptionsModal
        :isOpen="showExceptionsModal"
        :exceptions="exceptions"
        :defaultRules="defaultExceptions"
        @update:exceptions="exceptions = $event"
        @close="showExceptionsModal = false"
      />
    </div>
  </div>
</template>

<style scoped>
.tool-container.full-width {
  max-width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.tool-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  gap: 1.5rem;
  position: relative;
}

.panel-header {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  width: 100%;
}

.input-section {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.5rem;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
}

@media (max-width: 640px) {
  .input-section {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
  }
}

.input-wrapper {
  display: flex;
  gap: 1rem;
}

@media (max-width: 640px) {
  .input-wrapper {
    flex-direction: column;
  }

  .watch-toggle {
    justify-content: center;
  }

  .toggle-btn {
    width: 100%;
    justify-content: center;
  }
}

.url-input {
  flex: 1;
  padding: 0.8rem 1rem;
  border-radius: 8px;
  border: 1px solid var(--toggle-border);
  background: var(--toggle-bg);
  color: var(--text-color);
  font-size: 1rem;
  outline: none;
  transition: all 0.2s;
  resize: vertical;
  min-height: 46px;
  font-family: inherit;
}

.url-input:focus {
  border-color: var(--primary-accent);
  box-shadow: 0 0 0 2px rgba(var(--primary-accent-rgb), 0.2);
}

.watch-toggle {
  display: flex;
  justify-content: flex-end;
}

.toggle-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  position: relative;
}

.toggle-btn.active {
  background: rgba(var(--primary-accent-rgb), 0.2);
  border-color: var(--primary-accent);
  color: var(--primary-accent);
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #4ade80; /* Green */
  box-shadow: 0 0 8px #4ade80;
  margin-left: 0.2rem;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}

.history-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
}

.history-header {
  padding: 1rem;
  border-bottom: 1px solid var(--glass-border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.history-header h3 {
  margin: 0;
  font-size: 1.1rem;
  color: var(--text-strong);
}

.history-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.history-list {
  flex: 1;
  overflow-y: auto;
  padding: 0;
}

.history-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.8rem;
  border-bottom: 1px solid var(--glass-border);
  transition: background 0.2s;
}

.history-item:last-child {
  border-bottom: none;
}

.history-item:hover {
  background: var(--list-hover-bg);
}

.item-info {
  flex: 1;
  overflow: hidden;
  padding-right: 1rem;
}

.cleaned-url {
  color: var(--primary-accent);
  font-family: monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 0.4rem;
}

.meta-info {
  display: flex;
  gap: 1rem;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.savings {
  color: #4ade80;
  display: flex;
  align-items: center;
  gap: 0.2rem;
}

:global(:root[data-theme="light"]) .savings {
  color: #16a34a;
  font-weight: 500;
}

.item-actions {
  display: flex;
  gap: 0.5rem;
}

.icon-btn {
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 0.4rem;
  border-radius: 4px;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-btn:hover {
  color: var(--text-color);
  background: rgba(255, 255, 255, 0.1);
}

.delete-btn:hover {
  background: none;
  color: #ef4444;
}

:global(:root[data-theme="light"]) .delete-btn:hover {
  background: none;
  color: #dc2626;
}

.empty-state {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  color: var(--text-secondary);
  text-align: center;
  padding: 2rem;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}

.settings-btn {
  background: rgba(255, 255, 255, 0.1);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  color: var(--text-secondary);
  transition: all 0.3s ease;
}

.settings-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  color: var(--primary-accent);
}

:global(:root[data-theme="light"]) .settings-btn {
  background: rgba(0, 0, 0, 0.05);
}

:global(:root[data-theme="light"]) .settings-btn:hover {
  background: rgba(0, 0, 0, 0.1);
}
</style>
