<template>
  <div
    class="add-background-page"
    @dragenter.prevent="handleDragEnter"
    @dragover.prevent="handleDragOver"
    @dragleave="handleDragLeave"
    @drop.prevent="handleDrop"
  >
    <div v-if="isDragging" class="global-drag-overlay">
      <div class="overlay-content">
        <p>{{ t('Drop image anywhere to add background') }}</p>
      </div>
    </div>
    <input
      ref="fileInputRef"
      type="file"
      accept="image/*"
      style="display: none"
      @change="handleFileSelect"
    />
    
    <div class="page-header">
      <h2>{{ t('Add Background') }}</h2>
      <div v-if="uploadedImage" class="toolbar-actions">
        <button
          v-if="resultImage"
          class="toolbar-btn"
          @click="handleDownload"
          :title="t('Download')"
        >
          <i class="fa fa-download"></i>
        </button>
        <button 
          class="toolbar-btn"
          @click="resetUpload"
          :title="t('Change Image')"
        >
          <i class="fa fa-refresh"></i>
        </button>
      </div>
    </div>

    <div class="page-content">
      <div class="tool-container">
        <div class="upload-section">
          <div
            v-if="!uploadedImage"
            class="upload-area"
            :class="{ 'dragging': isDragging }"
          >
            <div class="upload-content">
              <button
                type="button"
                class="upload-btn"
                @click="triggerFileInput"
                :disabled="processing"
              >
                <i class="fa fa-upload"></i>
                <span>{{ t('Upload Image') }}</span>
              </button>
              
              <div class="divider">
                <span>{{ t('or') }}</span>
              </div>
              
              <div class="url-input-wrapper" @click.stop>
                <input
                  ref="urlInputRef"
                  v-model="imageUrl"
                  type="text"
                  class="url-input"
                  :placeholder="t('Paste image URL here')"
                  @keyup.enter="handleUrlSubmit"
                  @paste="handleUrlPaste"
                  :disabled="processing"
                />
              </div>
              
              <p class="upload-hint">{{ t('Drag and drop your image anywhere, or paste image directly') }}</p>
              <p class="upload-format-hint">{{ t('Supports JPG, PNG, WebP formats') }}</p>
            </div>
            <div v-if="processing" class="upload-processing-overlay">
              <div class="spinner"></div>
              <p>{{ t('Loading image from URL...') }}</p>
            </div>
          </div>

          <div v-else class="preview-section">
            <!-- Background Color Selection -->
            <div v-if="uploadedImage && !processing" class="background-controls">
              <div class="control-group">
                <label class="control-label">{{ t('Background Color') }}</label>
                <div class="color-picker-container">
                  <input
                    v-model="backgroundColor"
                    type="color"
                    class="color-picker"
                  />
                  <input
                    v-model="backgroundColor"
                    type="text"
                    class="hex-input"
                    placeholder="#FFFFFF"
                    @input="validateHexColor"
                  />
                </div>
              </div>
              
              <div class="action-buttons">
                <button
                  class="apply-btn"
                  @click="applyBackgroundColor"
                  :disabled="processing || !isColorValid"
                >
                  {{ t('Apply Background') }}
                </button>
              </div>
            </div>

            <div class="canvas-container" v-show="uploadedImage">
              <canvas 
                ref="canvasRef" 
                class="preview-canvas"
              ></canvas>
              <div v-if="processing" class="canvas-processing-overlay">
                <div class="spinner"></div>
                <p>{{ t('Applying background...') }}</p>
              </div>
            </div>
          </div>
        </div>

        <div v-if="historyList.length > 0 || uploadedImage" class="history-bar">
          <div class="history-scroll-container">
            <button 
              type="button"
              class="history-item add-button"
              @click.stop="triggerFileInput"
              :title="t('Add New Image')"
            >
              <i class="fa fa-plus"></i>
            </button>

            <div
              v-for="(item, index) in historyList"
              :key="item.id"
              class="history-item"
              :class="{ 'active': currentHistoryIndex === index }"
              @click="selectHistoryItem(index)"
            >
              <div class="history-thumbnail">
                <img :src="getHistoryThumbnailUrl(item)" alt="History" />
                <button
                  type="button"
                  class="history-delete-btn"
                  @click.stop="removeHistoryItem(index)"
                  :title="t('Delete')"
                  :aria-label="t('Delete')"
                ></button>
              </div>
            </div>

            <div
              v-if="uploadedImage && resultImage && currentHistoryIndex === -1"
              class="history-item active"
            >
              <div class="history-thumbnail">
                <img :src="resultImageUrl" alt="Current" />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { useMessage } from 'naive-ui'
import { useRoute } from 'vue-router'
import axios from 'axios'
import { t } from '@/shared/i18n'
import { get_session_api_headers } from '@/shared/api/auth'
import { useAuthStore } from '@/shared/stores/auth'
import { useSEO } from '@/shared/composables/useSEO'
import { compressImageFile } from '@/shared/utils/imageResize'
import { Canvas, FabricImage } from 'fabric'

const message = useMessage()
const authStore = useAuthStore()
const route = useRoute()

// SEO configuration
useSEO({
  title: t('Add Background'),
  description: t('Add custom background color to images. Free online tool to add background to transparent images. Supports JPG, PNG, WebP formats.'),
  keywords: t('add background, background color, image background, transparent background, online background tool, image processing, background editor, free tool')
})

interface HistoryItem {
  id: string
  originalImageUrl: string
  originalImageFile: File | null
  resultImage: string
  backgroundColor: string
  timestamp: number
}

const fileInputRef = ref<HTMLInputElement | null>(null)
const urlInputRef = ref<HTMLInputElement | null>(null)
const canvasRef = ref<HTMLCanvasElement | null>(null)
const uploadedImage = ref<File | null>(null)
const uploadedImageUrl = ref<string>('')
const resultImage = ref<string>('')
const resultImageBlobUrl = ref<string>('')
const imageUrl = ref<string>('')
const backgroundColor = ref<string>('#FFFFFF')
const isColorValid = ref<boolean>(true)
const resultImageUrl = computed(() => {
  if (!resultImage.value) return ''
  return resultImage.value
})

const historyList = ref<HistoryItem[]>([])
const currentHistoryIndex = ref<number>(-1)
const isDragging = ref(false)
const dragCounter = ref(0)
const processing = ref(false)
let fabricCanvas: Canvas | null = null

const adjustCanvasSize = () => {
  const canvas = canvasRef.value
  if (!canvas) return
  
  const previewSection = canvas.closest('.preview-section') as HTMLElement
  if (!previewSection) return
  
  const previewRect = previewSection.getBoundingClientRect()
  const padding = 24
  const maxAvailableWidth = Math.max(0, previewRect.width - padding)
  const maxAvailableHeight = Math.max(0, previewRect.height - 200) // Account for controls
  
  if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0) return
  
  canvas.style.maxWidth = `${maxAvailableWidth}px`
  canvas.style.maxHeight = `${maxAvailableHeight}px`
}

watch(uploadedImageUrl, adjustCanvasSize)

const handleResize = () => {
  adjustCanvasSize()
}

const handlePaste = async (event: ClipboardEvent) => {
  const items = event.clipboardData?.items
  if (!items) return

  for (let i = 0; i < items.length; i++) {
    const item = items[i]
    if (item.type.indexOf('image') !== -1) {
      event.preventDefault()
      const file = item.getAsFile()
      if (file) {
        processFile(file)
      }
      return
    }
  }

  const text = event.clipboardData?.getData('text')
  if (text && isValidImageUrl(text)) {
    event.preventDefault()
    imageUrl.value = text.trim()
    await handleUrlSubmit()
  }
}

const isValidImageUrl = (url: string): boolean => {
  if (!url || typeof url !== 'string') return false
  try {
    const urlObj = new URL(url)
    if (!['http:', 'https:'].includes(urlObj.protocol)) {
      return false
    }
    
    const pathname = urlObj.pathname.toLowerCase()
    const imageExtensions = ['.jpg', '.jpeg', '.png', '.webp', '.gif', '.bmp']
    
    const hasImageExtension = imageExtensions.some(ext => pathname.endsWith(ext)) || 
                              urlObj.pathname.match(/\.(jpg|jpeg|png|webp|gif|bmp)(\?|$)/i) !== null
    
    return hasImageExtension || pathname.length > 0
  } catch {
    return false
  }
}

const handleUrlPaste = async (event: ClipboardEvent) => {
  const text = event.clipboardData?.getData('text')
  if (text && isValidImageUrl(text)) {
    event.preventDefault()
    imageUrl.value = text.trim()
    await handleUrlSubmit()
  }
}

const handleUrlSubmit = async () => {
  const url = imageUrl.value.trim()
  if (!url) {
    message.warning(t('Please enter an image URL'))
    return
  }

  if (!isValidImageUrl(url)) {
    message.warning(t('Please enter a valid image URL'))
    return
  }

  processing.value = true
  resultImage.value = ''
  currentHistoryIndex.value = -1

  try {
    const response = await fetch(url, { mode: 'cors' })
    if (!response.ok) {
      throw new Error(`Failed to load image: ${response.status}`)
    }

    const blob = await response.blob()
    
    const validTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp']
    if (!validTypes.includes(blob.type)) {
      message.warning(t('Unsupported image format. Please use JPG, PNG, or WebP'))
      processing.value = false
      return
    }

    const maxSize = 10 * 1024 * 1024
    if (blob.size > maxSize) {
      message.warning(t('Image size exceeds 10MB limit'))
      processing.value = false
      return
    }

    const originalFile = new File([blob], 'image-from-url', { type: blob.type })
    
    try {
      const compressedFile = await compressImageFile(originalFile, {
        maxWidth: 1024,
        maxHeight: 1024,
        quality: 0.92,
        mode: 'contain'
      })
      
      uploadedImage.value = compressedFile
      uploadedImageUrl.value = URL.createObjectURL(compressedFile)
      
      await initializeCanvas()
    } catch (error) {
      message.error(t('Image processing failed, please try again'))
      processing.value = false
    }
  } catch (error: any) {
    let errorMessage = t('Failed to load image from URL')
    
    if (error.message?.includes('CORS')) {
      errorMessage = t('CORS error. The image server does not allow cross-origin access.')
    } else if (error.message?.includes('Failed to load')) {
      errorMessage = t('Failed to load image. Please check the URL and try again.')
    }
    
    message.error(errorMessage)
    processing.value = false
  }
}

onMounted(() => {
  window.addEventListener('resize', handleResize)
  window.addEventListener('paste', handlePaste)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  window.removeEventListener('paste', handlePaste)
  if (uploadedImageUrl.value && uploadedImageUrl.value.startsWith('blob:')) {
    URL.revokeObjectURL(uploadedImageUrl.value)
  }
  if (resultImageBlobUrl.value) {
    URL.revokeObjectURL(resultImageBlobUrl.value)
  }
  if (fabricCanvas) {
    fabricCanvas.dispose()
    fabricCanvas = null
  }
})

const triggerFileInput = () => {
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
    fileInputRef.value.click()
  }
}

const handleFileSelect = (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]
  if (file) {
    processFile(file)
  }
}

const hasFiles = (event: DragEvent) => {
  const types = event.dataTransfer?.types
  if (!types) return false
  return Array.from(types).includes('Files')
}

const handleDragEnter = (event: DragEvent) => {
  if (!hasFiles(event)) return
  dragCounter.value += 1
  isDragging.value = true
}

const handleDragOver = (event: DragEvent) => {
  if (!hasFiles(event)) return
  event.dataTransfer!.dropEffect = 'copy'
  isDragging.value = true
}

const handleDragLeave = (event: DragEvent) => {
  if (!hasFiles(event)) return
  dragCounter.value = Math.max(0, dragCounter.value - 1)
  if (dragCounter.value === 0) {
    isDragging.value = false
  }
}

const handleDrop = (event: DragEvent) => {
  if (!hasFiles(event)) return
  event.preventDefault()
  dragCounter.value = 0
  isDragging.value = false
  const file = event.dataTransfer?.files[0]
  if (file && file.type.startsWith('image/')) {
    processFile(file)
  } else {
    message.warning(t('Please upload an image file'))
  }
}

const processFile = async (file: File) => {
  const validTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp']
  if (!validTypes.includes(file.type)) {
    message.warning(t('Unsupported image format. Please use JPG, PNG, or WebP'))
    return
  }

  const maxSize = 10 * 1024 * 1024
  if (file.size > maxSize) {
    message.warning(t('Image size exceeds 10MB limit'))
    return
  }

  try {
    const compressedFile = await compressImageFile(file, {
      maxWidth: 1024,
      maxHeight: 1024,
      quality: 0.92,
      mode: 'contain'
    })
    
    uploadedImage.value = compressedFile
    resultImage.value = ''
    currentHistoryIndex.value = -1
    
    const reader = new FileReader()
    reader.onload = async (e) => {
      uploadedImageUrl.value = e.target?.result as string
      await initializeCanvas()
    }
    reader.readAsDataURL(compressedFile)
  } catch (error) {
    message.error(t('Image processing failed, please try again'))
  }
}

const initializeCanvas = async () => {
  if (!canvasRef.value || !uploadedImageUrl.value) {
    processing.value = false
    return
  }
  
  try {
    await nextTick()
    
    // Clean up old canvas
    if (fabricCanvas) {
      fabricCanvas.dispose()
      fabricCanvas = null
    }
    
    // Create new fabric canvas
    fabricCanvas = new Canvas(canvasRef.value, {
      selection: false
    })
    
    // Load image using fabric v7 API
    const img = await FabricImage.fromURL(uploadedImageUrl.value, {
      crossOrigin: 'anonymous'
    })
    
    if (!img || !fabricCanvas) {
      processing.value = false
      return
    }
    
    const previewSection = canvasRef.value?.closest('.preview-section') as HTMLElement
    if (!previewSection) {
      processing.value = false
      return
    }
    
    const previewRect = previewSection.getBoundingClientRect()
    const padding = 100
    const maxAvailableWidth = Math.max(400, previewRect.width - padding)
    const maxAvailableHeight = Math.max(400, previewRect.height - 300)
    
    const imgWidth = img.width || 1
    const imgHeight = img.height || 1
    
    const scale = Math.min(
      maxAvailableWidth / imgWidth,
      maxAvailableHeight / imgHeight,
      1
    )
    
    img.scale(scale)
    
    const canvasWidth = img.getScaledWidth()
    const canvasHeight = img.getScaledHeight()
    
    // Use setDimensions for fabric v7
    fabricCanvas.setDimensions({ width: canvasWidth, height: canvasHeight })
    
    img.set({
      left: 0,
      top: 0,
      selectable: false,
      evented: false
    })
    
    fabricCanvas.add(img)
    fabricCanvas.centerObject(img)
    fabricCanvas.renderAll()
    
    processing.value = false
  } catch (error) {
    console.error('Canvas initialization error:', error)
    message.error(t('Failed to load image'))
    processing.value = false
  }
}

const validateHexColor = () => {
  const hex = backgroundColor.value.trim()
  const isValid = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex)
  isColorValid.value = isValid
  return isValid
}

const applyBackgroundColor = async () => {
  if (!fabricCanvas || !uploadedImage.value) {
    message.warning(t('Please upload an image first'))
    return
  }
  
  if (!validateHexColor()) {
    message.warning(t('Please enter a valid hex color code'))
    return
  }

  processing.value = true
  resultImage.value = ''

  try {
    const objects = fabricCanvas.getObjects()
    
    if (objects.length === 0) {
      throw new Error('No image found on canvas')
    }
    
    // Set background color using fabric v7 API
    fabricCanvas.backgroundColor = backgroundColor.value
    fabricCanvas.renderAll()
    
    // Export to data URL using fabric v7 API
    const dataUrl = fabricCanvas.toDataURL({
      format: 'png',
      quality: 0.95,
      multiplier: 1
    })
    
    resultImage.value = dataUrl
    await cacheResultImage(dataUrl)
    
    // Add to history
    if (currentHistoryIndex.value === -1 && uploadedImage.value && uploadedImageUrl.value) {
      const historyItem: HistoryItem = {
        id: `history-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
        originalImageUrl: uploadedImageUrl.value,
        originalImageFile: uploadedImage.value,
        resultImage: dataUrl,
        backgroundColor: backgroundColor.value,
        timestamp: Date.now()
      }
      historyList.value.unshift(historyItem)
      currentHistoryIndex.value = 0
    } else if (currentHistoryIndex.value >= 0) {
      historyList.value[currentHistoryIndex.value].resultImage = dataUrl
      historyList.value[currentHistoryIndex.value].backgroundColor = backgroundColor.value
    }
    
    message.success(t('Background applied successfully'))
    
  } catch (error: any) {
    console.error('Apply background error:', error)
    message.error(error.message || t('Failed to apply background'))
  } finally {
    processing.value = false
  }
}

const resetUpload = () => {
  if (uploadedImageUrl.value && uploadedImageUrl.value.startsWith('blob:')) {
    URL.revokeObjectURL(uploadedImageUrl.value)
  }
  if (resultImageBlobUrl.value) {
    URL.revokeObjectURL(resultImageBlobUrl.value)
    resultImageBlobUrl.value = ''
  }
  if (fabricCanvas) {
    fabricCanvas.dispose()
    fabricCanvas = null
  }
  uploadedImage.value = null
  uploadedImageUrl.value = ''
  resultImage.value = ''
  imageUrl.value = ''
  backgroundColor.value = '#FFFFFF'
  currentHistoryIndex.value = -1
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
  }
}

const selectHistoryItem = async (index: number) => {
  if (index < 0 || index >= historyList.value.length) return
  
  const item = historyList.value[index]
  currentHistoryIndex.value = index
  uploadedImageUrl.value = item.originalImageUrl
  resultImage.value = item.resultImage
  backgroundColor.value = item.backgroundColor
  uploadedImage.value = item.originalImageFile
  
  if (item.resultImage) {
    await cacheResultImage(item.resultImage)
  }
  
  // Initialize canvas and apply saved background color
  await initializeCanvasWithBackground(item.backgroundColor)
}

const initializeCanvasWithBackground = async (bgColor: string) => {
  if (!canvasRef.value || !uploadedImageUrl.value) {
    processing.value = false
    return
  }
  
  try {
    await nextTick()
    
    // Clean up old canvas
    if (fabricCanvas) {
      fabricCanvas.dispose()
      fabricCanvas = null
    }
    
    // Create new fabric canvas
    fabricCanvas = new Canvas(canvasRef.value, {
      selection: false
    })
    
    // Load image using fabric v7 API
    const img = await FabricImage.fromURL(uploadedImageUrl.value, {
      crossOrigin: 'anonymous'
    })
    
    if (!img || !fabricCanvas) {
      processing.value = false
      return
    }
    
    const previewSection = canvasRef.value?.closest('.preview-section') as HTMLElement
    if (!previewSection) {
      processing.value = false
      return
    }
    
    const previewRect = previewSection.getBoundingClientRect()
    const padding = 100
    const maxAvailableWidth = Math.max(400, previewRect.width - padding)
    const maxAvailableHeight = Math.max(400, previewRect.height - 300)
    
    const imgWidth = img.width || 1
    const imgHeight = img.height || 1
    
    const scale = Math.min(
      maxAvailableWidth / imgWidth,
      maxAvailableHeight / imgHeight,
      1
    )
    
    img.scale(scale)
    
    const canvasWidth = img.getScaledWidth()
    const canvasHeight = img.getScaledHeight()
    
    // Use setDimensions for fabric v7
    fabricCanvas.setDimensions({ width: canvasWidth, height: canvasHeight })
    
    img.set({
      left: 0,
      top: 0,
      selectable: false,
      evented: false
    })
    
    // Apply saved background color if provided
    if (bgColor) {
      fabricCanvas.backgroundColor = bgColor
    }
    
    fabricCanvas.add(img)
    fabricCanvas.centerObject(img)
    fabricCanvas.renderAll()
    
    processing.value = false
  } catch (error) {
    console.error('Canvas initialization error:', error)
    message.error(t('Failed to load image'))
    processing.value = false
  }
}

const getHistoryThumbnailUrl = (item: HistoryItem): string => {
  if (item.resultImage) {
    return item.resultImage
  }
  return item.originalImageUrl
}

const cacheResultImage = async (imageUrl: string) => {
  try {
    if (resultImageBlobUrl.value) {
      URL.revokeObjectURL(resultImageBlobUrl.value)
      resultImageBlobUrl.value = ''
    }
    
    const response = await fetch(imageUrl)
    if (!response.ok) {
      throw new Error(`Failed to fetch image: ${response.status}`)
    }
    const blob = await response.blob()
    resultImageBlobUrl.value = URL.createObjectURL(blob)
  } catch (error) {
    // Cache failure doesn't affect display
  }
}

const handleDownload = async () => {
  if (!resultImage.value) return

  try {
    let blobUrl = resultImageBlobUrl.value
    
    if (!blobUrl) {
      const response = await fetch(resultImage.value)
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }
      const blob = await response.blob()
      blobUrl = URL.createObjectURL(blob)
      resultImageBlobUrl.value = blobUrl
    }
    
    const link = document.createElement('a')
    link.href = blobUrl
    link.download = `background-added-${Date.now()}.png`
    link.style.display = 'none'
    
    document.body.appendChild(link)
    link.click()
    
    requestAnimationFrame(() => {
      document.body.removeChild(link)
    })
  } catch (error: any) {
    message.error(t('Failed to download image'))
  }
}

const removeHistoryItem = (index: number) => {
  if (index < 0 || index >= historyList.value.length) return

  const removingCurrent = currentHistoryIndex.value === index
  historyList.value.splice(index, 1)

  if (historyList.value.length === 0) {
    currentHistoryIndex.value = -1
    resetUpload()
    return
  }

  if (removingCurrent) {
    const nextIndex = Math.min(index, historyList.value.length - 1)
    selectHistoryItem(nextIndex)
  } else if (currentHistoryIndex.value > index) {
    currentHistoryIndex.value -= 1
  }
}
</script>

<style scoped lang="scss">
.add-background-page {
  position: relative;
  width: calc(100% + 40px);
  height: calc(100vh - 64px - 40px);
  margin: -20px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.global-drag-overlay {
  position: fixed;
  inset: 0;
  background: radial-gradient(circle at center, rgba(248, 250, 252, 0.92), rgba(248, 250, 252, 0.82));
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  pointer-events: none;
  animation: fade-in 0.15s ease;

  &::before {
    content: '';
    position: absolute;
    width: 55vmax;
    height: 55vmax;
    border-radius: 35%;
    border: 1px solid rgba(148, 163, 184, 0.25);
    animation: rotate 12s linear infinite;
    pointer-events: none;
  }
}

.overlay-content {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 18px 30px;
  color: #0f172a;
  font-size: 18px;
  font-weight: 600;
  text-align: center;
  letter-spacing: 0.04em;

  &::before {
    content: '';
    position: absolute;
    inset: -10px;
    border-radius: 999px;
    border: 1px solid rgba(79, 70, 229, 0.35);
    opacity: 0.7;
    animation: pulse-line 1.8s ease-out infinite;
  }

  &::after {
    content: '';
    position: absolute;
    inset: -28px 16px;
    border-radius: 999px;
    background: linear-gradient(90deg, rgba(59, 130, 246, 0), rgba(59, 130, 246, 0.24), rgba(59, 130, 246, 0));
    filter: blur(10px);
    opacity: 0.65;
    animation: shimmer 2.4s linear infinite;
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: scale(0.98);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}

@keyframes pulse-line {
  0% {
    transform: scale(0.9);
    opacity: 0;
  }
  50% {
    transform: scale(1);
    opacity: 0.5;
  }
  100% {
    transform: scale(1.05);
    opacity: 0;
  }
}

@keyframes shimmer {
  0% {
    opacity: 0.2;
  }
  50% {
    opacity: 0.7;
  }
  100% {
    opacity: 0.2;
  }
}

.page-header {
  flex-shrink: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 12px 36px;
}

.page-content {
  flex: 1;
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

.page-header h2 {
  font-size: 20px;
  font-weight: 600;
  color: #1f2937;
  margin: 0;
}

.toolbar-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.toolbar-btn {
  width: 36px;
  height: 36px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: white;
  color: #64748b;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;

  i {
    font-size: 14px;
  }

  &:hover {
    border-color: #1fc76f;
    color: #1fc76f;
    background: #f0fdf4;
  }

  &:active {
    transform: scale(0.95);
  }
}

.tool-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

.upload-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  border: 1px solid #e5e7eb;
}

.upload-section:has(.preview-section) {
  padding: 0;
  border-radius: 0;
  border: none;
  box-shadow: none;
  background: transparent;
}

.upload-area {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dashed #cbd5e1;
  border-radius: 12px;
  padding: 48px 32px;
  text-align: center;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  background: #fafbfc;
  min-height: 0;
  position: relative;

  &:hover {
    border-color: #1fc76f;
    background: #f0fdf4;
  }

  &.dragging {
    border-color: #1fc76f;
    background: #ecfdf5;
    border-style: solid;
  }
}

.upload-processing-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  border-radius: 12px;
  backdrop-filter: blur(4px);
  z-index: 10;

  p {
    font-size: 14px;
    color: #64748b;
    margin: 0;
    font-weight: 500;
  }
}

.upload-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: 100%;
  max-width: 500px;
}

.upload-btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 20px 40px;
  background: #e6f8f0;
  color: #0d684b;
  border: 1px solid #1fc76f;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  white-space: nowrap;

  i {
    font-size: 16px;
  }

  &:hover:not(:disabled) {
    background: #dcfce7;
    border-color: #1fc76f;
    color: #166534;
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(31, 199, 111, 0.15);
  }

  &:active:not(:disabled) {
    background: #1fc76f;
    border-color: #1fc76f;
    color: white;
    transform: translateY(0);
    box-shadow: 0 1px 4px rgba(31, 199, 111, 0.2);
  }

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    background: #f1f5f9;
    border-color: #e2e8f0;
    color: #94a3b8;
  }

  &:disabled:hover {
    transform: none;
    box-shadow: none;
  }
}

.divider {
  display: flex;
  align-items: center;
  color: #94a3b8;
  font-size: 13px;
  width: 100%;
  max-width: 300px;

  &::before,
  &::after {
    content: '';
    flex: 1;
    height: 1px;
    background: #e5e7eb;
  }

  span {
    padding: 0 12px;
  }
}

.upload-hint {
  font-size: 13px;
  color: #64748b;
  margin: 0;
  line-height: 1.5;
}

.upload-format-hint {
  font-size: 12px;
  color: #94a3b8;
  margin: 0;
}

.url-input-wrapper {
  width: 100%;
  max-width: 500px;
}

.url-input {
  width: 100%;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 12px 16px;
  font-size: 14px;
  color: #1f2937;
  background: white;
  outline: none;
  transition: all 0.2s ease;

  &::placeholder {
    color: #94a3b8;
  }

  &:focus {
    border-color: #1fc76f;
    box-shadow: 0 0 0 3px rgba(31, 199, 111, 0.1);
  }

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    background: #f8fafc;
  }
}

.preview-section {
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
  padding: 12px;
}

.background-controls {
  flex-shrink: 0;
  padding: 20px;
  background: #f8fafc;
  border-bottom: 1px solid #e5e7eb;
}

.control-group {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}

.control-label {
  font-size: 14px;
  font-weight: 600;
  color: #64748b;
  min-width: 120px;
}

.color-picker-container {
  display: flex;
  align-items: center;
  gap: 12px;
}

.color-picker {
  width: 48px;
  height: 48px;
  border: 2px solid #e5e7eb;
  border-radius: 8px;
  cursor: pointer;
  background: none;
  
  &::-webkit-color-swatch-wrapper {
    padding: 0;
  }
  
  &::-webkit-color-swatch {
    border: none;
    border-radius: 6px;
  }
}

.hex-input {
  width: 120px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 14px;
  font-family: monospace;
  color: #1f2937;
  background: white;
  outline: none;
  transition: all 0.2s ease;

  &:focus {
    border-color: #1fc76f;
    box-shadow: 0 0 0 3px rgba(31, 199, 111, 0.1);
  }

  &.invalid {
    border-color: #ef4444;
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
  }
}

.action-buttons {
  display: flex;
  justify-content: center;
}

.apply-btn {
  padding: 12px 32px;
  background: #1fc76f;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover:not(:disabled) {
    background: #16a34a;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(31, 199, 111, 0.3);
  }

  &:active:not(:disabled) {
    transform: translateY(0);
  }

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
  }
}

.canvas-container {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: auto;
  min-height: 400px;
  padding: 20px;
}

.preview-canvas {
  max-width: 100%;
  max-height: 100%;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.canvas-processing-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  backdrop-filter: blur(4px);

  p {
    font-size: 14px;
    color: #64748b;
    margin: 0;
  }
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #e5e7eb;
  border-top-color: #1fc76f;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.history-bar {
  flex-shrink: 0;
  width: 100%;
  padding: 12px 0;
  background: transparent;
  display: flex;
  justify-content: center;
}

.history-scroll-container {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0;
  scrollbar-width: thin;
  scrollbar-color: #cbd5e1 transparent;

  &::-webkit-scrollbar {
    height: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
  }

  &::-webkit-scrollbar-thumb {
    background: #cbd5e1;
    border-radius: 3px;

    &:hover {
      background: #94a3b8;
    }
  }
}

.history-item {
  flex-shrink: 0;
  width: 56px;
  height: 56px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;

  &.add-button {
    background: white;
    border: 2px dashed #cbd5e1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #64748b;
    transition: all 0.2s ease;
    padding: 0;
    margin: 0;
    outline: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;

    i {
      font-size: 24px;
      pointer-events: none;
    }

    &:hover {
      border-color: #1fc76f;
      color: #1fc76f;
      background: #f0fdf4;
    }

    &:active {
      transform: scale(0.95);
    }

    &:focus {
      outline: none;
      border-color: #1fc76f;
    }
  }

  &.active {
    .history-thumbnail {
      border-color: #1fc76f;
      box-shadow: 0 0 10px rgba(31, 199, 111, 0.35);
    }
  }
}

.history-thumbnail {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  border: 2px solid #e5e7eb;
  overflow: hidden;
  position: relative;
  background: 
    linear-gradient(45deg, #f1f5f9 25%, transparent 25%),
    linear-gradient(-45deg, #f1f5f9 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #f1f5f9 75%),
    linear-gradient(-45deg, transparent 75%, #f1f5f9 75%);
  background-size: 10px 10px;
  background-position: 0 0, 0 5px, 5px -5px, -5px 0px;
  transition: all 0.2s ease;

  img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
  }

  &:hover {
    border-color: #1fc76f;
  }

  .history-delete-btn {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 18px;
    height: 18px;
    border-radius: 999px;
    border: none;
    background: rgba(15, 23, 42, 0.6);
    color: white;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transform: scale(0.9);
    transition: all 0.2s ease;
    cursor: pointer;
    font-size: 0;
    line-height: 1;

    &::before,
    &::after {
      content: '';
      position: absolute;
      width: 10px;
      height: 2px;
      background: white;
      border-radius: 999px;
    }

    &::before {
      transform: rotate(45deg);
    }

    &::after {
      transform: rotate(-45deg);
    }

    &:hover {
      background: rgba(239, 68, 68, 0.85);
    }
  }

  &:hover .history-delete-btn {
    opacity: 1;
    transform: scale(1);
  }
}

@media (max-width: 768px) {
  .page-header {
    padding: 10px 12px;
  }

  .page-header h2 {
    font-size: 18px;
  }

  .page-content {
    padding: 8px 12px;
  }

  .upload-section {
    padding: 16px;
  }

  .upload-area {
    padding: 32px 16px;
  }

  .upload-content {
    gap: 14px;
    max-width: 100%;
  }

  .upload-btn {
    width: 100%;
    justify-content: center;
    padding: 18px 32px;
    font-size: 15px;

    i {
      font-size: 15px;
    }
  }

  .divider {
    max-width: 100%;
  }

  .url-input-wrapper {
    width: 100%;
    max-width: 100%;
  }

  .url-input {
    font-size: 12px;
    padding: 6px 10px;
  }

  .preview-section {
    padding: 8px;
  }

  .background-controls {
    padding: 16px;
  }

  .control-group {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .control-label {
    min-width: auto;
  }

  .color-picker-container {
    width: 100%;
  }

  .hex-input {
    flex: 1;
  }

  .history-bar {
    padding: 10px 0;
  }

  .history-item {
    width: 48px;
    height: 48px;
  }

  .history-scroll-container {
    gap: 8px;
    padding: 0 8px;
  }

  .toolbar-btn {
    width: 32px;
    height: 32px;

    i {
      font-size: 12px;
    }
  }
}
</style>