import type { ThemeVariables, Theme, DesignTokens } from '../stores/theme'
import { apiFetch } from '@/lib/tauri'

// Uses relative URLs - works with Vite proxy in dev and Traefik in production
const API_URL = ''

// =====================
// API Client
// =====================

export const themesApi = {
  async getAll(): Promise<Theme[]> {
    const res = await apiFetch(`${API_URL}/api/themes`)
    return res.json()
  },

  async getById(id: string): Promise<Theme | null> {
    const res = await apiFetch(`${API_URL}/api/themes/${id}`)
    if (!res.ok) return null
    return res.json()
  },

  async getActive(): Promise<Theme | null> {
    const res = await apiFetch(`${API_URL}/api/themes/active`)
    if (!res.ok) return null
    return res.json()
  },

  async save(theme: Partial<Theme>): Promise<{ success: boolean; id: string }> {
    const res = await apiFetch(`${API_URL}/api/themes`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(theme)
    })
    return res.json()
  },

  async delete(id: string): Promise<{ success: boolean; error?: string }> {
    const res = await apiFetch(`${API_URL}/api/themes/${id}`, { method: 'DELETE' })
    return res.json()
  },

  async setDefault(id: string): Promise<{ success: boolean }> {
    const res = await apiFetch(`${API_URL}/api/themes/${id}/default`, { method: 'POST' })
    return res.json()
  },

  async getDesignTokens(): Promise<DesignTokens> {
    const res = await apiFetch(`${API_URL}/api/design-tokens`)
    return res.json()
  },

  getExportUrl(id: string): string {
    return `${API_URL}/api/themes/export/${id}`
  }
}

// =====================
// CSS Utilities
// =====================

export function variablesToCSS(variables: ThemeVariables): string {
  const lines: string[] = [':root {']

  for (const [category, vars] of Object.entries(variables)) {
    lines.push(`  /* ${category} */`)
    for (const [key, value] of Object.entries(vars as Record<string, string>)) {
      lines.push(`  --${key}: ${value};`)
    }
    lines.push('')
  }

  lines.push('}')
  return lines.join('\n')
}

export function parseColorValue(value: string): { hex: string; alpha: number } {
  // Handle rgba
  const rgbaMatch = value.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/)
  if (rgbaMatch) {
    const r = rgbaMatch[1] || '0'
    const g = rgbaMatch[2] || '0'
    const b = rgbaMatch[3] || '0'
    const a = rgbaMatch[4]
    const hex = `#${[r, g, b].map(x => parseInt(x).toString(16).padStart(2, '0')).join('')}`
    return { hex, alpha: a ? parseFloat(a) : 1 }
  }

  // Handle hex with alpha
  if (value.length === 9 && value.startsWith('#')) {
    const alpha = parseInt(value.slice(7), 16) / 255
    return { hex: value.slice(0, 7), alpha }
  }

  return { hex: value, alpha: 1 }
}

export function isColorVariable(key: string): boolean {
  const colorKeywords = ['bg', 'text', 'color', 'accent', 'success', 'warning', 'error', 'info', 'border']
  return colorKeywords.some(kw => key.toLowerCase().includes(kw))
}

export function isSizeVariable(key: string): boolean {
  const sizeKeywords = ['radius', 'size', 'spacing', 'width', 'height']
  return sizeKeywords.some(kw => key.toLowerCase().includes(kw))
}

export function isTransitionVariable(key: string): boolean {
  return key.toLowerCase().includes('transition')
}

export function isShadowVariable(key: string): boolean {
  return key.toLowerCase().includes('shadow')
}

export function isFontVariable(key: string): boolean {
  return key.toLowerCase().includes('font')
}

// =====================
// Color Manipulation
// =====================

export function hexToRGB(hex: string): { r: number; g: number; b: number } {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
  if (!result) return { r: 0, g: 0, b: 0 }
  return {
    r: parseInt(result[1] || '0', 16),
    g: parseInt(result[2] || '0', 16),
    b: parseInt(result[3] || '0', 16)
  }
}

export function rgbToHex(r: number, g: number, b: number): string {
  return '#' + [r, g, b].map(x => Math.round(x).toString(16).padStart(2, '0')).join('')
}

export function hexToHSL(hex: string): { h: number; s: number; l: number } {
  const { r, g, b } = hexToRGB(hex)
  const rNorm = r / 255
  const gNorm = g / 255
  const bNorm = b / 255

  const max = Math.max(rNorm, gNorm, bNorm)
  const min = Math.min(rNorm, gNorm, bNorm)
  let h = 0
  let s = 0
  const l = (max + min) / 2

  if (max !== min) {
    const d = max - min
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
    switch (max) {
      case rNorm:
        h = ((gNorm - bNorm) / d + (gNorm < bNorm ? 6 : 0)) / 6
        break
      case gNorm:
        h = ((bNorm - rNorm) / d + 2) / 6
        break
      case bNorm:
        h = ((rNorm - gNorm) / d + 4) / 6
        break
    }
  }

  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    l: Math.round(l * 100)
  }
}

export function hslToHex(h: number, s: number, l: number): string {
  s /= 100
  l /= 100

  const a = s * Math.min(l, 1 - l)
  const f = (n: number) => {
    const k = (n + h / 30) % 12
    const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)
    return Math.round(255 * color)
      .toString(16)
      .padStart(2, '0')
  }
  return `#${f(0)}${f(8)}${f(4)}`
}

export function lighten(hex: string, amount: number): string {
  const { h, s, l } = hexToHSL(hex)
  return hslToHex(h, s, Math.min(100, l + amount))
}

export function darken(hex: string, amount: number): string {
  const { h, s, l } = hexToHSL(hex)
  return hslToHex(h, s, Math.max(0, l - amount))
}

export function generateColorScale(baseColor: string, steps = 10): string[] {
  const { h, s } = hexToHSL(baseColor)
  const scale: string[] = []

  for (let i = 0; i < steps; i++) {
    const l = 95 - i * 9 // From 95% to 5% lightness
    scale.push(hslToHex(h, s, Math.max(5, Math.min(95, l))))
  }

  return scale
}

export function getContrastColor(hex: string): string {
  const { r, g, b } = hexToRGB(hex)
  const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
  return luminance > 0.5 ? '#000000' : '#ffffff'
}

// =====================
// Theme Categories
// =====================

export const THEME_CATEGORIES = [
  { key: 'colors', label: 'Backgrounds', icon: 'square' },
  { key: 'text', label: 'Text', icon: 'type' },
  { key: 'accent', label: 'Accent', icon: 'zap' },
  { key: 'semantic', label: 'Semantic', icon: 'alert-circle' },
  { key: 'spacing', label: 'Spacing', icon: 'maximize' },
  { key: 'typography', label: 'Typography', icon: 'text' },
  { key: 'effects', label: 'Effects', icon: 'layers' }
] as const

export type ThemeCategory = (typeof THEME_CATEGORIES)[number]['key']

// =====================
// Validation
// =====================

export function validateTheme(theme: Partial<Theme>): { valid: boolean; errors: string[] } {
  const errors: string[] = []

  if (!theme.name?.trim()) {
    errors.push('Theme name is required')
  }

  if (!theme.variables) {
    errors.push('Theme variables are required')
  } else {
    const requiredCategories = ['colors', 'text', 'accent']
    for (const cat of requiredCategories) {
      if (!(cat in theme.variables)) {
        errors.push(`Missing required category: ${cat}`)
      }
    }
  }

  return { valid: errors.length === 0, errors }
}

// =====================
// File Operations
// =====================

export function downloadTheme(theme: Theme): void {
  const data = JSON.stringify(
    {
      name: theme.name,
      description: theme.description,
      variables: theme.variables,
      metadata: {
        ...theme.metadata,
        exported_at: new Date().toISOString()
      }
    },
    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 = `${theme.name.toLowerCase().replace(/\s+/g, '-')}-theme.json`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

export async function readThemeFile(file: File): Promise<Partial<Theme>> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => {
      try {
        const data = JSON.parse(reader.result as string)
        if (!data.name || !data.variables) {
          reject(new Error('Invalid theme file format'))
        }
        resolve(data)
      } catch {
        reject(new Error('Failed to parse theme file'))
      }
    }
    reader.onerror = () => reject(new Error('Failed to read file'))
    reader.readAsText(file)
  })
}
