"use client"

import React from 'react'
import { ComponentInstance } from './store'

export interface WireframeElement {
  id: string
  type: 'rect' | 'circle' | 'text' | 'path' | 'line' | 'group'
  x: number
  y: number
  width: number
  height: number
  fill?: string
  stroke?: string
  strokeWidth?: number
  text?: string
  fontSize?: number
  fontFamily?: string
  fontWeight?: string
  rx?: number
  ry?: number
  cx?: number
  cy?: number
  r?: number
  children?: WireframeElement[]
}

export interface ParsedWireframe {
  elements: WireframeElement[]
  width: number
  height: number
  deviceType: 'desktop' | 'tablet' | 'mobile'
}

/**
 * Converts SVG wireframe data to React components for the component canvas
 */
export class WireframeToComponentsConverter {
  private static instance: WireframeToComponentsConverter
  private componentCounter = 0

  static getInstance(): WireframeToComponentsConverter {
    if (!WireframeToComponentsConverter.instance) {
      WireframeToComponentsConverter.instance = new WireframeToComponentsConverter()
    }
    return WireframeToComponentsConverter.instance
  }

  /**
   * Parse SVG string and extract wireframe elements
   */
  parseSVGToWireframe(svgString: string, deviceType: 'desktop' | 'tablet' | 'mobile' = 'desktop'): ParsedWireframe {
    try {
      const parser = new DOMParser()
      const svgDoc = parser.parseFromString(svgString, 'image/svg+xml')
      const svgElement = svgDoc.querySelector('svg')
      
      if (!svgElement) {
        throw new Error('No SVG element found')
      }

      // Get SVG dimensions
      const viewBox = svgElement.getAttribute('viewBox')
      let width = 800
      let height = 600
      
      if (viewBox) {
        const values = viewBox.split(/\s+|,/).map(Number).filter(n => !isNaN(n))
        if (values.length >= 4) {
          width = values[2]
          height = values[3]
        }
      } else {
        const widthAttr = svgElement.getAttribute('width')
        const heightAttr = svgElement.getAttribute('height')
        if (widthAttr && heightAttr) {
          width = parseFloat(widthAttr.replace(/px|pt|em|rem|%/g, '')) || 800
          height = parseFloat(heightAttr.replace(/px|pt|em|rem|%/g, '')) || 600
        }
      }

      const elements = this.parseSVGElements(svgElement)
      
      return {
        elements,
        width,
        height,
        deviceType
      }
    } catch (error) {
      console.error('Error parsing SVG:', error)
      return {
        elements: [],
        width: 800,
        height: 600,
        deviceType
      }
    }
  }

  /**
   * Parse SVG elements recursively
   */
  private parseSVGElements(svgElement: Element): WireframeElement[] {
    const elements: WireframeElement[] = []
    
    Array.from(svgElement.children).forEach((element) => {
      const tagName = element.tagName.toLowerCase()
      
      // Skip non-visual elements
      if (['defs', 'style', 'title', 'desc', 'metadata', 'clippath', 'mask'].includes(tagName)) {
        return
      }

      const wireframeElement = this.parseElement(element)
      if (wireframeElement) {
        elements.push(wireframeElement)
      }
    })

    return elements
  }

  /**
   * Parse individual SVG element
   */
  private parseElement(element: Element): WireframeElement | null {
    const tagName = element.tagName.toLowerCase()
    const id = element.getAttribute('id') || `element-${++this.componentCounter}`
    
    // Check visibility
    const visibility = element.getAttribute('visibility')
    const display = element.getAttribute('display')
    const opacity = element.getAttribute('opacity')
    
    if (visibility === 'hidden' || display === 'none' || opacity === '0') {
      return null
    }

    switch (tagName) {
      case 'rect':
        return this.parseRect(element as SVGRectElement, id)
      case 'circle':
        return this.parseCircle(element as SVGCircleElement, id)
      case 'ellipse':
        return this.parseEllipse(element as SVGEllipseElement, id)
      case 'text':
        return this.parseText(element as SVGTextElement, id)
      case 'path':
        return this.parsePath(element as SVGPathElement, id)
      case 'line':
        return this.parseLine(element as SVGLineElement, id)
      case 'g':
        return this.parseGroup(element, id)
      default:
        return null
    }
  }

  private parseRect(element: SVGRectElement, id: string): WireframeElement {
    const x = parseFloat(element.getAttribute('x') || '0')
    const y = parseFloat(element.getAttribute('y') || '0')
    const width = parseFloat(element.getAttribute('width') || '100')
    const height = parseFloat(element.getAttribute('height') || '100')
    const fill = element.getAttribute('fill') || 'none'
    const stroke = element.getAttribute('stroke') || '#000000'
    const strokeWidth = parseFloat(element.getAttribute('stroke-width') || '1')
    const rx = parseFloat(element.getAttribute('rx') || '0')
    const ry = parseFloat(element.getAttribute('ry') || '0')

    return {
      id,
      type: 'rect',
      x,
      y,
      width,
      height,
      fill,
      stroke,
      strokeWidth,
      rx,
      ry
    }
  }

  private parseCircle(element: SVGCircleElement, id: string): WireframeElement {
    const cx = parseFloat(element.getAttribute('cx') || '0')
    const cy = parseFloat(element.getAttribute('cy') || '0')
    const r = parseFloat(element.getAttribute('r') || '50')
    const fill = element.getAttribute('fill') || 'none'
    const stroke = element.getAttribute('stroke') || '#000000'
    const strokeWidth = parseFloat(element.getAttribute('stroke-width') || '1')

    return {
      id,
      type: 'circle',
      x: cx - r,
      y: cy - r,
      width: r * 2,
      height: r * 2,
      fill,
      stroke,
      strokeWidth,
      cx,
      cy,
      r
    }
  }

  private parseEllipse(element: SVGEllipseElement, id: string): WireframeElement {
    const cx = parseFloat(element.getAttribute('cx') || '0')
    const cy = parseFloat(element.getAttribute('cy') || '0')
    const rx = parseFloat(element.getAttribute('rx') || '50')
    const ry = parseFloat(element.getAttribute('ry') || '30')
    const fill = element.getAttribute('fill') || 'none'
    const stroke = element.getAttribute('stroke') || '#000000'
    const strokeWidth = parseFloat(element.getAttribute('stroke-width') || '1')

    return {
      id,
      type: 'circle',
      x: cx - rx,
      y: cy - ry,
      width: rx * 2,
      height: ry * 2,
      fill,
      stroke,
      strokeWidth,
      cx,
      cy,
      r: rx
    }
  }

  private parseText(element: SVGTextElement, id: string): WireframeElement {
    const x = parseFloat(element.getAttribute('x') || '0')
    const y = parseFloat(element.getAttribute('y') || '0')
    const text = element.textContent || ''
    const fill = element.getAttribute('fill') || '#000000'
    const fontSize = parseFloat(element.getAttribute('font-size') || '16')
    const fontFamily = element.getAttribute('font-family') || 'sans-serif'
    const fontWeight = element.getAttribute('font-weight') || 'normal'

    // Estimate text dimensions
    const estimatedWidth = text.length * (fontSize * 0.6)
    const estimatedHeight = fontSize

    return {
      id,
      type: 'text',
      x,
      y,
      width: estimatedWidth,
      height: estimatedHeight,
      fill,
      text,
      fontSize,
      fontFamily,
      fontWeight
    }
  }

  private parsePath(element: SVGPathElement, id: string): WireframeElement {
    const d = element.getAttribute('d') || ''
    const fill = element.getAttribute('fill') || 'none'
    const stroke = element.getAttribute('stroke') || '#000000'
    const strokeWidth = parseFloat(element.getAttribute('stroke-width') || '1')

    // For paths, we'll create a bounding box
    // This is a simplified approach - in a real implementation, you'd parse the path data
    const bounds = this.getPathBounds(d)
    
    return {
      id,
      type: 'path',
      x: bounds.x,
      y: bounds.y,
      width: bounds.width,
      height: bounds.height,
      fill,
      stroke,
      strokeWidth
    }
  }

  private parseLine(element: SVGLineElement, id: string): WireframeElement {
    const x1 = parseFloat(element.getAttribute('x1') || '0')
    const y1 = parseFloat(element.getAttribute('y1') || '0')
    const x2 = parseFloat(element.getAttribute('x2') || '0')
    const y2 = parseFloat(element.getAttribute('y2') || '0')
    const stroke = element.getAttribute('stroke') || '#000000'
    const strokeWidth = parseFloat(element.getAttribute('stroke-width') || '1')

    const x = Math.min(x1, x2)
    const y = Math.min(y1, y2)
    const width = Math.abs(x2 - x1)
    const height = Math.abs(y2 - y1)

    return {
      id,
      type: 'line',
      x,
      y,
      width,
      height,
      stroke,
      strokeWidth
    }
  }

  private parseGroup(element: Element, id: string): WireframeElement {
    const children = this.parseSVGElements(element)
    
    // Calculate group bounds
    let minX = Infinity
    let minY = Infinity
    let maxX = -Infinity
    let maxY = -Infinity

    children.forEach(child => {
      minX = Math.min(minX, child.x)
      minY = Math.min(minY, child.y)
      maxX = Math.max(maxX, child.x + child.width)
      maxY = Math.max(maxY, child.y + child.height)
    })

    return {
      id,
      type: 'group',
      x: minX === Infinity ? 0 : minX,
      y: minY === Infinity ? 0 : minY,
      width: maxX === -Infinity ? 0 : maxX - minX,
      height: maxY === -Infinity ? 0 : maxY - minY,
      children
    }
  }

  private getPathBounds(d: string): { x: number; y: number; width: number; height: number } {
    // Simplified path bounds calculation
    // In a real implementation, you'd parse the path data properly
    return { x: 0, y: 0, width: 100, height: 50 }
  }

  /**
   * Convert wireframe elements to React components
   */
  convertToComponents(wireframe: ParsedWireframe): ComponentInstance[] {
    const components: ComponentInstance[] = []
    
    wireframe.elements.forEach((element, index) => {
      const component = this.elementToComponent(element, index)
      if (component) {
        components.push(component)
      }
    })

    return components
  }

  /**
   * Convert a single wireframe element to a React component
   */
  private elementToComponent(element: WireframeElement, index: number): ComponentInstance | null {
    const baseProps = {
      x: element.x,
      y: element.y,
      width: element.width,
      height: element.height,
      fill: element.fill,
      stroke: element.stroke,
      strokeWidth: element.strokeWidth
    }

    switch (element.type) {
      case 'rect':
        return {
          id: `wireframe-${element.id}-${index}`,
          type: 'wireframe-rect',
          props: {
            ...baseProps,
            rx: element.rx || 0,
            ry: element.ry || 0
          },
          position: { x: element.x, y: element.y },
          size: { width: element.width, height: element.height }
        }

      case 'circle':
        return {
          id: `wireframe-${element.id}-${index}`,
          type: 'wireframe-circle',
          props: {
            ...baseProps,
            cx: element.cx || element.x + element.width / 2,
            cy: element.cy || element.y + element.height / 2,
            r: element.r || Math.min(element.width, element.height) / 2
          },
          position: { x: element.x, y: element.y },
          size: { width: element.width, height: element.height }
        }

      case 'text':
        return {
          id: `wireframe-${element.id}-${index}`,
          type: 'wireframe-text',
          props: {
            ...baseProps,
            text: element.text || '',
            fontSize: element.fontSize || 16,
            fontFamily: element.fontFamily || 'sans-serif',
            fontWeight: element.fontWeight || 'normal'
          },
          position: { x: element.x, y: element.y },
          size: { width: element.width, height: element.height }
        }

      case 'line':
        return {
          id: `wireframe-${element.id}-${index}`,
          type: 'wireframe-line',
          props: baseProps,
          position: { x: element.x, y: element.y },
          size: { width: element.width, height: element.height }
        }

      case 'path':
        return {
          id: `wireframe-${element.id}-${index}`,
          type: 'wireframe-path',
          props: baseProps,
          position: { x: element.x, y: element.y },
          size: { width: element.width, height: element.height }
        }

      case 'group':
        // For groups, we'll create a container component
        return {
          id: `wireframe-${element.id}-${index}`,
          type: 'wireframe-group',
          props: {
            ...baseProps,
            children: element.children || []
          },
          position: { x: element.x, y: element.y },
          size: { width: element.width, height: element.height }
        }

      default:
        return null
    }
  }

  /**
   * Convert wireframe to a single SVG component for display
   */
  convertToSVGComponent(wireframe: ParsedWireframe): ComponentInstance {
    const timestamp = Date.now()
    const randomId = Math.random().toString(36).substr(2, 9)
    return {
      id: `wireframe-svg-${timestamp}-${randomId}`,
      type: 'wireframe-svg',
      props: {
        elements: wireframe.elements,
        width: wireframe.width,
        height: wireframe.height,
        deviceType: wireframe.deviceType
      },
      position: { x: 0, y: 0 },
      size: { width: wireframe.width, height: wireframe.height }
    }
  }
}

export const wireframeConverter = WireframeToComponentsConverter.getInstance()
