/**
 * BreakPilot Compliance SDK - Embed Script
 *
 * Usage:
 * <script src="https://cdn.breakpilot.app/sdk/v1/compliance.min.js"></script>
 * <script>
 *   BreakPilotSDK.init({
 *     apiEndpoint: 'https://compliance.example.com/api/v1',
 *     apiKey: 'pk_live_xxx',
 *     autoInjectBanner: true,
 *     bannerConfig: { position: 'bottom', theme: 'dark', language: 'de' }
 *   });
 * </script>
 */

import { ComplianceClient } from '@breakpilot/compliance-sdk-core'
import type {
  ConsentPurpose,
  CookieBannerPosition,
  CookieBannerTheme,
  DSRRequestType,
} from '@breakpilot/compliance-sdk-types'

// ============================================================================
// Types
// ============================================================================

export interface BreakPilotSDKConfig {
  apiEndpoint: string
  apiKey: string
  tenantId?: string
  autoInjectBanner?: boolean
  bannerConfig?: BannerConfig
  onConsentChange?: (consents: Record<ConsentPurpose, boolean>) => void
  onReady?: () => void
  onError?: (error: Error) => void
  debug?: boolean
}

export interface BannerConfig {
  position?: CookieBannerPosition
  theme?: CookieBannerTheme
  language?: 'de' | 'en'
  privacyPolicyUrl?: string
  imprintUrl?: string
  texts?: {
    title?: string
    description?: string
    acceptAll?: string
    rejectAll?: string
    settings?: string
    save?: string
  }
  customColors?: {
    background?: string
    text?: string
    primary?: string
    secondary?: string
  }
}

// ============================================================================
// Internal State
// ============================================================================

let _client: ComplianceClient | null = null
let _config: BreakPilotSDKConfig | null = null
let _consents: Record<ConsentPurpose, boolean> = {
  ESSENTIAL: true,
  FUNCTIONAL: false,
  ANALYTICS: false,
  MARKETING: false,
  PERSONALIZATION: false,
  THIRD_PARTY: false,
}
let _bannerElement: HTMLElement | null = null
let _isInitialized = false

// ============================================================================
// Translations
// ============================================================================

const TRANSLATIONS = {
  de: {
    title: 'Cookie-Einwilligung',
    description:
      'Wir verwenden Cookies, um Ihre Erfahrung zu verbessern. Weitere Informationen finden Sie in unserer Datenschutzerklärung.',
    acceptAll: 'Alle akzeptieren',
    rejectAll: 'Nur notwendige',
    settings: 'Einstellungen',
    save: 'Speichern',
    privacy: 'Datenschutz',
    imprint: 'Impressum',
    categories: {
      ESSENTIAL: { name: 'Notwendig', description: 'Erforderlich für die Grundfunktionen' },
      FUNCTIONAL: { name: 'Funktional', description: 'Verbesserte Funktionen' },
      ANALYTICS: { name: 'Analyse', description: 'Nutzungsstatistiken' },
      MARKETING: { name: 'Marketing', description: 'Personalisierte Werbung' },
      PERSONALIZATION: { name: 'Personalisierung', description: 'Angepasste Inhalte' },
      THIRD_PARTY: { name: 'Drittanbieter', description: 'Externe Dienste' },
    },
  },
  en: {
    title: 'Cookie Consent',
    description:
      'We use cookies to improve your experience. For more information, please see our privacy policy.',
    acceptAll: 'Accept All',
    rejectAll: 'Reject Non-Essential',
    settings: 'Settings',
    save: 'Save',
    privacy: 'Privacy Policy',
    imprint: 'Imprint',
    categories: {
      ESSENTIAL: { name: 'Essential', description: 'Required for basic functionality' },
      FUNCTIONAL: { name: 'Functional', description: 'Enhanced features' },
      ANALYTICS: { name: 'Analytics', description: 'Usage statistics' },
      MARKETING: { name: 'Marketing', description: 'Personalized advertising' },
      PERSONALIZATION: { name: 'Personalization', description: 'Customized content' },
      THIRD_PARTY: { name: 'Third Party', description: 'External services' },
    },
  },
}

// ============================================================================
// Utility Functions
// ============================================================================

function log(message: string, ...args: unknown[]): void {
  if (_config?.debug) {
    console.log(`[BreakPilotSDK] ${message}`, ...args)
  }
}

function getStoredConsents(): Record<ConsentPurpose, boolean> | null {
  try {
    const stored = localStorage.getItem('breakpilot_consents')
    return stored ? JSON.parse(stored) : null
  } catch {
    return null
  }
}

function storeConsents(consents: Record<ConsentPurpose, boolean>): void {
  try {
    localStorage.setItem('breakpilot_consents', JSON.stringify(consents))
    localStorage.setItem('breakpilot_consents_timestamp', Date.now().toString())
  } catch {
    log('Failed to store consents')
  }
}

function createElement<K extends keyof HTMLElementTagNameMap>(
  tag: K,
  styles: Partial<CSSStyleDeclaration> = {},
  attributes: Record<string, string> = {}
): HTMLElementTagNameMap[K] {
  const el = document.createElement(tag)
  Object.assign(el.style, styles)
  Object.entries(attributes).forEach(([key, value]) => el.setAttribute(key, value))
  return el
}

// ============================================================================
// Banner Implementation
// ============================================================================

function createBanner(): HTMLElement {
  const config = _config!
  const bannerConfig = config.bannerConfig || {}
  const lang = bannerConfig.language || 'de'
  const t = TRANSLATIONS[lang]
  const position = bannerConfig.position || 'BOTTOM'
  const theme = bannerConfig.theme || 'LIGHT'

  const isDark = theme === 'DARK'
  const bgColor = bannerConfig.customColors?.background || (isDark ? '#1a1a1a' : '#ffffff')
  const textColor = bannerConfig.customColors?.text || (isDark ? '#ffffff' : '#1a1a1a')
  const primaryColor = bannerConfig.customColors?.primary || (isDark ? '#ffffff' : '#1a1a1a')
  const secondaryColor = bannerConfig.customColors?.secondary || (isDark ? '#ffffff' : '#1a1a1a')

  // Container
  const container = createElement(
    'div',
    {
      position: 'fixed',
      zIndex: '99999',
      left: position === 'CENTER' ? '50%' : '0',
      right: position === 'CENTER' ? 'auto' : '0',
      top: position === 'TOP' ? '0' : position === 'CENTER' ? '50%' : 'auto',
      bottom: position === 'BOTTOM' ? '0' : 'auto',
      transform: position === 'CENTER' ? 'translate(-50%, -50%)' : 'none',
      maxWidth: position === 'CENTER' ? '500px' : 'none',
      backgroundColor: bgColor,
      color: textColor,
      padding: '20px',
      boxShadow: '0 -2px 10px rgba(0, 0, 0, 0.1)',
      fontFamily: 'system-ui, -apple-system, sans-serif',
      fontSize: '14px',
      lineHeight: '1.5',
    },
    { id: 'breakpilot-consent-banner', role: 'dialog', 'aria-label': t.title }
  )

  // Title
  const title = createElement('h3', {
    margin: '0 0 10px',
    fontSize: '18px',
    fontWeight: '600',
  })
  title.textContent = bannerConfig.texts?.title || t.title

  // Description
  const description = createElement('p', {
    margin: '0 0 15px',
    opacity: '0.8',
  })
  description.textContent = bannerConfig.texts?.description || t.description

  // Buttons container
  const buttonsContainer = createElement('div', {
    display: 'flex',
    flexWrap: 'wrap',
    gap: '10px',
    alignItems: 'center',
  })

  // Accept All button
  const acceptBtn = createElement(
    'button',
    {
      padding: '10px 20px',
      borderRadius: '4px',
      border: 'none',
      cursor: 'pointer',
      fontWeight: '500',
      backgroundColor: primaryColor,
      color: isDark ? '#1a1a1a' : '#ffffff',
    },
    { type: 'button' }
  )
  acceptBtn.textContent = bannerConfig.texts?.acceptAll || t.acceptAll
  acceptBtn.onclick = () => handleAcceptAll()

  // Reject button
  const rejectBtn = createElement(
    'button',
    {
      padding: '10px 20px',
      borderRadius: '4px',
      backgroundColor: 'transparent',
      border: `1px solid ${secondaryColor}`,
      color: textColor,
      cursor: 'pointer',
      fontWeight: '500',
    },
    { type: 'button' }
  )
  rejectBtn.textContent = bannerConfig.texts?.rejectAll || t.rejectAll
  rejectBtn.onclick = () => handleRejectAll()

  // Settings button
  const settingsBtn = createElement(
    'button',
    {
      padding: '10px 20px',
      borderRadius: '4px',
      backgroundColor: 'transparent',
      border: `1px solid ${secondaryColor}`,
      color: textColor,
      cursor: 'pointer',
      fontWeight: '500',
    },
    { type: 'button' }
  )
  settingsBtn.textContent = bannerConfig.texts?.settings || t.settings
  settingsBtn.onclick = () => showSettingsPanel()

  // Links container
  const linksContainer = createElement('div', {
    marginLeft: 'auto',
    fontSize: '12px',
  })

  const privacyLink = createElement('a', {
    marginRight: '15px',
    color: textColor,
    textDecoration: 'none',
  })
  privacyLink.href = bannerConfig.privacyPolicyUrl || '/privacy'
  privacyLink.textContent = t.privacy

  const imprintLink = createElement('a', {
    color: textColor,
    textDecoration: 'none',
  })
  imprintLink.href = bannerConfig.imprintUrl || '/imprint'
  imprintLink.textContent = t.imprint

  // Assemble
  linksContainer.appendChild(privacyLink)
  linksContainer.appendChild(imprintLink)

  buttonsContainer.appendChild(acceptBtn)
  buttonsContainer.appendChild(rejectBtn)
  buttonsContainer.appendChild(settingsBtn)
  buttonsContainer.appendChild(linksContainer)

  container.appendChild(title)
  container.appendChild(description)
  container.appendChild(buttonsContainer)

  return container
}

function showSettingsPanel(): void {
  if (!_bannerElement) return

  const config = _config!
  const bannerConfig = config.bannerConfig || {}
  const lang = bannerConfig.language || 'de'
  const t = TRANSLATIONS[lang]
  const theme = bannerConfig.theme || 'LIGHT'
  const isDark = theme === 'DARK'
  const textColor = bannerConfig.customColors?.text || (isDark ? '#ffffff' : '#1a1a1a')

  // Clear banner content
  _bannerElement.innerHTML = ''

  // Title
  const title = createElement('h3', {
    margin: '0 0 15px',
    fontSize: '18px',
    fontWeight: '600',
  })
  title.textContent = t.settings

  _bannerElement.appendChild(title)

  // Categories
  const categories: ConsentPurpose[] = [
    'ESSENTIAL',
    'FUNCTIONAL',
    'ANALYTICS',
    'MARKETING',
  ]

  categories.forEach(category => {
    const catInfo = t.categories[category]
    const row = createElement('div', {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '10px 0',
      borderBottom: `1px solid ${isDark ? '#333' : '#eee'}`,
    })

    const labelContainer = createElement('div', {})
    const labelName = createElement('div', { fontWeight: '500' })
    labelName.textContent = catInfo.name
    const labelDesc = createElement('div', { fontSize: '12px', opacity: '0.7' })
    labelDesc.textContent = catInfo.description

    labelContainer.appendChild(labelName)
    labelContainer.appendChild(labelDesc)

    const checkbox = createElement(
      'input',
      {
        width: '20px',
        height: '20px',
        cursor: category === 'ESSENTIAL' ? 'not-allowed' : 'pointer',
      },
      {
        type: 'checkbox',
        'data-category': category,
      }
    )
    checkbox.checked = _consents[category]
    checkbox.disabled = category === 'ESSENTIAL'
    checkbox.onchange = () => {
      if (category !== 'ESSENTIAL') {
        _consents[category] = checkbox.checked
      }
    }

    row.appendChild(labelContainer)
    row.appendChild(checkbox)
    _bannerElement!.appendChild(row)
  })

  // Buttons
  const buttonsContainer = createElement('div', {
    display: 'flex',
    flexWrap: 'wrap',
    gap: '10px',
    marginTop: '15px',
  })

  const primaryColor = bannerConfig.customColors?.primary || (isDark ? '#ffffff' : '#1a1a1a')
  const secondaryColor = bannerConfig.customColors?.secondary || (isDark ? '#ffffff' : '#1a1a1a')

  const saveBtn = createElement(
    'button',
    {
      padding: '10px 20px',
      borderRadius: '4px',
      border: 'none',
      cursor: 'pointer',
      fontWeight: '500',
      backgroundColor: primaryColor,
      color: isDark ? '#1a1a1a' : '#ffffff',
    },
    { type: 'button' }
  )
  saveBtn.textContent = bannerConfig.texts?.save || t.save
  saveBtn.onclick = () => handleSaveSettings()

  const backBtn = createElement(
    'button',
    {
      padding: '10px 20px',
      borderRadius: '4px',
      backgroundColor: 'transparent',
      border: `1px solid ${secondaryColor}`,
      color: textColor,
      cursor: 'pointer',
      fontWeight: '500',
    },
    { type: 'button' }
  )
  backBtn.textContent = 'Zurück'
  backBtn.onclick = () => showMainBanner()

  buttonsContainer.appendChild(saveBtn)
  buttonsContainer.appendChild(backBtn)
  _bannerElement.appendChild(buttonsContainer)
}

function showMainBanner(): void {
  if (_bannerElement) {
    _bannerElement.remove()
  }
  _bannerElement = createBanner()
  document.body.appendChild(_bannerElement)
}

function hideBanner(): void {
  if (_bannerElement) {
    _bannerElement.remove()
    _bannerElement = null
  }
}

// ============================================================================
// Consent Handlers
// ============================================================================

function handleAcceptAll(): void {
  _consents = {
    ESSENTIAL: true,
    FUNCTIONAL: true,
    ANALYTICS: true,
    MARKETING: true,
    PERSONALIZATION: true,
    THIRD_PARTY: true,
  }
  applyConsents()
}

function handleRejectAll(): void {
  _consents = {
    ESSENTIAL: true,
    FUNCTIONAL: false,
    ANALYTICS: false,
    MARKETING: false,
    PERSONALIZATION: false,
    THIRD_PARTY: false,
  }
  applyConsents()
}

function handleSaveSettings(): void {
  applyConsents()
}

function applyConsents(): void {
  storeConsents(_consents)
  hideBanner()
  _config?.onConsentChange?.(_consents)
  log('Consents applied:', _consents)
}

// ============================================================================
// Public API
// ============================================================================

function init(config: BreakPilotSDKConfig): void {
  if (_isInitialized) {
    log('SDK already initialized')
    return
  }

  _config = config
  log('Initializing with config:', config)

  try {
    _client = new ComplianceClient({
      apiEndpoint: config.apiEndpoint,
      apiKey: config.apiKey,
      tenantId: config.tenantId,
    })

    // Check for stored consents
    const storedConsents = getStoredConsents()
    if (storedConsents) {
      _consents = storedConsents
      log('Loaded stored consents:', _consents)
      config.onConsentChange?.(storedConsents)
    } else if (config.autoInjectBanner !== false) {
      // Show banner if no stored consents
      showMainBanner()
    }

    _isInitialized = true
    config.onReady?.()
    log('SDK initialized successfully')
  } catch (error) {
    const err = error instanceof Error ? error : new Error(String(error))
    config.onError?.(err)
    log('SDK initialization failed:', err)
  }
}

function getConsents(): Record<ConsentPurpose, boolean> {
  return { ..._consents }
}

function updateConsent(purpose: ConsentPurpose, granted: boolean): void {
  if (purpose === 'ESSENTIAL') {
    log('Cannot change essential consent')
    return
  }
  _consents[purpose] = granted
  storeConsents(_consents)
  _config?.onConsentChange?.(_consents)
  log('Consent updated:', purpose, granted)
}

function showBanner(): void {
  showMainBanner()
}

function hasConsent(purpose: ConsentPurpose): boolean {
  return _consents[purpose]
}

function getClient(): ComplianceClient | null {
  return _client
}

async function submitDSR(
  type: DSRRequestType,
  email: string,
  name: string
): Promise<{ success: boolean; requestId?: string; error?: string }> {
  if (!_client) {
    return { success: false, error: 'SDK not initialized' }
  }

  try {
    // This would call the DSR endpoint
    log('Submitting DSR:', { type, email, name })
    // In a real implementation, this would use the client to submit
    return { success: true, requestId: `dsr_${Date.now()}` }
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown error'
    return { success: false, error: message }
  }
}

function destroy(): void {
  hideBanner()
  _client = null
  _config = null
  _isInitialized = false
  log('SDK destroyed')
}

// ============================================================================
// Export for IIFE
// ============================================================================

export const BreakPilotSDK = {
  init,
  getConsents,
  updateConsent,
  showBanner,
  hideBanner,
  hasConsent,
  getClient,
  submitDSR,
  destroy,
  version: '0.0.1',
}

// Auto-attach to window for script tag usage
if (typeof window !== 'undefined') {
  ;(window as unknown as Record<string, unknown>).BreakPilotSDK = BreakPilotSDK
}

export default BreakPilotSDK
