import type { TileExpression } from './types'

export const GEOMETRIC_PATTERNS: Record<string, TileExpression> = {
  'checker': {
    name: 'Checkerboard',
    code: '(x + y) % 2',
    compiled: (x, y, i, t, size) => (x + y) % 2
  },
  'stripes_h': {
    name: 'Horizontal Stripes',
    code: 'y % 2',
    compiled: (x, y, i, t, size) => y % 2
  },
  'stripes_v': {
    name: 'Vertical Stripes',
    code: 'x % 2',
    compiled: (x, y, i, t, size) => x % 2
  },
  'diagonal': {
    name: 'Diagonal Lines',
    code: '(x - y) % 2',
    compiled: (x, y, i, t, size) => (x - y) % 2
  },
  'diamond': {
    name: 'Diamond Grid',
    code: '(x + y) % 4 < 2',
    compiled: (x, y, i, t, size) => (x + y) % 4 < 2
  },
  'cross': {
    name: 'Cross Pattern',
    code: 'x % 3 === 1 || y % 3 === 1',
    compiled: (x, y, i, t, size) => x % 3 === 1 || y % 3 === 1
  },
  'maze': {
    name: 'Maze Pattern',
    code: '(x % 4 === 0 && y % 2 === 0) || (y % 4 === 0 && x % 2 === 0)',
    compiled: (x, y, i, t, size) => (x % 4 === 0 && y % 2 === 0) || (y % 4 === 0 && x % 2 === 0)
  },
  'triangles': {
    name: 'Triangle Grid',
    code: '(x + y) % 3 === 0',
    compiled: (x, y, i, t, size) => (x + y) % 3 === 0
  },
  'hexagon': {
    name: 'Hexagonal',
    code: '(x % 6 + y % 4) % 3 === 0',
    compiled: (x, y, i, t, size) => (x % 6 + y % 4) % 3 === 0
  },
  'waves': {
    name: 'Wave Pattern',
    code: 'Math.sin(x * 0.5) + Math.sin(y * 0.5) > 0',
    compiled: (x, y, i, t, size) => Math.sin(x * 0.5) + Math.sin(y * 0.5) > 0
  },
  'spiral': {
    name: 'Spiral Arms',
    code: 'Math.atan2(y - size/2, x - size/2) + Math.sqrt((x - size/2)**2 + (y - size/2)**2) * 0.1',
    compiled: (x, y, i, t, size) => {
      const centerX = size / 2
      const centerY = size / 2
      const angle = Math.atan2(y - centerY, x - centerX)
      const distance = Math.sqrt((x - centerX)**2 + (y - centerY)**2)
      return Math.sin(angle * 3 + distance * 0.2) > 0
    }
  },
  'concentric': {
    name: 'Concentric Circles',
    code: 'Math.sqrt((x - size/2)**2 + (y - size/2)**2) % 8 < 4',
    compiled: (x, y, i, t, size) => {
      const centerX = size / 2
      const centerY = size / 2
      const distance = Math.sqrt((x - centerX)**2 + (y - centerY)**2)
      return distance % 8 < 4
    }
  },
  'plus': {
    name: 'Plus Pattern',
    code: '(x % 6 === 3) || (y % 6 === 3)',
    compiled: (x, y, i, t, size) => (x % 6 === 3) || (y % 6 === 3)
  },
  'bricks': {
    name: 'Brick Pattern',
    code: 'y % 4 < 2 ? x % 4 < 2 : (x + 2) % 4 < 2',
    compiled: (x, y, i, t, size) => y % 4 < 2 ? x % 4 < 2 : (x + 2) % 4 < 2
  },
  'dots': {
    name: 'Dot Grid',
    code: 'x % 4 === 2 && y % 4 === 2',
    compiled: (x, y, i, t, size) => x % 4 === 2 && y % 4 === 2
  },
  'zigzag': {
    name: 'Zigzag',
    code: '(x + Math.floor(y / 2)) % 4 < 2',
    compiled: (x, y, i, t, size) => (x + Math.floor(y / 2)) % 4 < 2
  },
  'random': {
    name: 'Random Noise',
    code: 'Math.sin(x * 12.9898 + y * 78.233) * 43758.5453 % 1 > 0.5',
    compiled: (x, y, i, t, size) => Math.sin(x * 12.9898 + y * 78.233) * 43758.5453 % 1 > 0.5
  },
  'voronoi': {
    name: 'Voronoi Cells',
    code: 'Voronoi-like pattern',
    compiled: (x, y, i, t, size) => {
      // Simple Voronoi approximation using distance to grid points
      const gridX = Math.floor(x / 8) * 8 + 4
      const gridY = Math.floor(y / 8) * 8 + 4
      const dx = x - gridX
      const dy = y - gridY
      return Math.sqrt(dx*dx + dy*dy) < 3
    }
  },
  'fractal': {
    name: 'Fractal Tree',
    code: 'Sierpinski-like pattern',
    compiled: (x, y, i, t, size) => {
      // Simple Sierpinski triangle approximation
      return (x & y) === 0
    }
  },
  'maze_complex': {
    name: 'Complex Maze',
    code: 'Complex maze pattern',
    compiled: (x, y, i, t, size) => {
      const hash = (x * 374761393 + y * 668265263) % 1000000
      return (hash % 3 === 0) && ((x % 4 === 0) || (y % 4 === 0))
    }
  },
  'arrows': {
    name: 'Arrow Pattern',
    code: 'Directional arrows',
    compiled: (x, y, i, t, size) => {
      const px = x % 8
      const py = y % 8
      return (px === 3 || px === 4) && (py >= px - 3 && py <= 11 - px)
    }
  },
  'stars': {
    name: 'Star Pattern',
    code: 'Eight-pointed stars',
    compiled: (x, y, i, t, size) => {
      const px = x % 12
      const py = y % 12
      const cx = 6
      const cy = 6
      const dx = Math.abs(px - cx)
      const dy = Math.abs(py - cy)
      return (dx + dy <= 4) && (dx <= 2 || dy <= 2)
    }
  },
  'circuit': {
    name: 'Circuit Board',
    code: 'Electronic circuit pattern',
    compiled: (x, y, i, t, size) => {
      return ((x % 8 === 0 || x % 8 === 7) && y % 4 === 0) ||
             ((y % 8 === 0 || y % 8 === 7) && x % 4 === 0) ||
             (x % 16 === 8 && y % 16 === 8)
    }
  },
  'tribal': {
    name: 'Tribal Pattern',
    code: 'Tribal geometric design',
    compiled: (x, y, i, t, size) => {
      const px = x % 16
      const py = y % 16
      return ((px + py) % 8 < 2) || ((px - py + 16) % 8 < 2)
    }
  },
  'islamic': {
    name: 'Islamic Tiles',
    code: 'Islamic geometric pattern',
    compiled: (x, y, i, t, size) => {
      const px = x % 24
      const py = y % 24
      return ((px + py) % 6 === 0) || ((px - py + 24) % 6 === 0) ||
             (px % 8 === 4 && py % 8 === 4)
    }
  },
  'weave': {
    name: 'Basket Weave',
    code: 'Woven pattern',
    compiled: (x, y, i, t, size) => {
      const blockX = Math.floor(x / 4) % 2
      const blockY = Math.floor(y / 4) % 2
      return blockX === blockY ? x % 2 === 0 : y % 2 === 0
    }
  },
  'scales': {
    name: 'Dragon Scales',
    code: 'Overlapping scale pattern',
    compiled: (x, y, i, t, size) => {
      const offset = (y % 8 < 4) ? 2 : 0
      const px = (x + offset) % 8
      const py = y % 8
      return py < 4 && px >= 2 && px <= 5
    }
  },
  'honeycomb': {
    name: 'Honeycomb',
    code: 'Hexagonal honeycomb',
    compiled: (x, y, i, t, size) => {
      const hex = (x % 6) + (y % 4) * 1.5
      return Math.floor(hex) % 3 === 0
    }
  },
  'labyrinth': {
    name: 'Labyrinth',
    code: 'Classical labyrinth',
    compiled: (x, y, i, t, size) => {
      const cx = size / 2
      const cy = size / 2
      const dx = x - cx
      const dy = y - cy
      const angle = Math.atan2(dy, dx)
      const radius = Math.sqrt(dx*dx + dy*dy)
      return Math.floor(radius + angle * 4) % 6 < 3
    }
  },
  'tetris': {
    name: 'Tetris Blocks',
    code: 'Tetris piece pattern',
    compiled: (x, y, i, t, size) => {
      const shapes = [
        [[1,1,1,1]], // I
        [[1,1],[1,1]], // O
        [[0,1,0],[1,1,1]], // T
        [[1,1,0],[0,1,1]], // S
      ]
      const shapeId = (Math.floor(x/4) + Math.floor(y/4)) % shapes.length
      const shape = shapes[shapeId]
      const sx = x % 4
      const sy = y % shape.length
      return sx < shape[sy]?.length && shape[sy][sx] === 1
    }
  },
  'aztec': {
    name: 'Aztec Pattern',
    code: 'Pre-Columbian design',
    compiled: (x, y, i, t, size) => {
      const px = x % 16
      const py = y % 16
      return ((px === 0 || px === 15) && (py >= 4 && py <= 11)) ||
             ((py === 0 || py === 15) && (px >= 4 && px <= 11)) ||
             ((px >= 6 && px <= 9) && (py >= 6 && py <= 9))
    }
  },
  'optical': {
    name: 'Optical Illusion',
    code: 'Op-art pattern',
    compiled: (x, y, i, t, size) => {
      const wave1 = Math.sin(x * 0.3) * 4
      const wave2 = Math.sin(y * 0.3) * 4
      return (x + wave1 + y + wave2) % 8 < 4
    }
  },
  'neurons': {
    name: 'Neural Network',
    code: 'Connected nodes',
    compiled: (x, y, i, t, size) => {
      const isNode = (x % 12 === 6) && (y % 12 === 6)
      const isConnection = ((x % 12 === 6) && (y % 4 === 0)) ||
                          ((y % 12 === 6) && (x % 4 === 0))
      return isNode || isConnection
    }
  },
  'dna': {
    name: 'DNA Helix',
    code: 'Double helix structure',
    compiled: (x, y, i, t, size) => {
      const helix1 = Math.sin(y * 0.5) * 4 + 8
      const helix2 = Math.sin(y * 0.5 + Math.PI) * 4 + 8
      return Math.abs(x - helix1) < 1.5 || Math.abs(x - helix2) < 1.5 ||
             (y % 8 === 0 && x >= Math.min(helix1, helix2) && x <= Math.max(helix1, helix2))
    }
  },
  'mandala': {
    name: 'Mandala Pattern',
    code: 'Radial mandala design',
    compiled: (x, y, i, t, size) => {
      const cx = size / 2
      const cy = size / 2
      const dx = x - cx
      const dy = y - cy
      const angle = Math.atan2(dy, dx)
      const radius = Math.sqrt(dx*dx + dy*dy)
      return Math.sin(angle * 8) * Math.sin(radius * 0.5) > 0
    }
  },
  'molecular': {
    name: 'Molecular Structure',
    code: 'Chemical bonds',
    compiled: (x, y, i, t, size) => {
      const atomX = x % 20 === 10
      const atomY = y % 20 === 10
      const bondH = (y % 20 === 10) && ((x % 10) < 2 || (x % 10) > 7)
      const bondV = (x % 20 === 10) && ((y % 10) < 2 || (y % 10) > 7)
      return (atomX && atomY) || bondH || bondV
    }
  },
  'cyberpunk': {
    name: 'Cyberpunk Grid',
    code: 'Futuristic data pattern',
    compiled: (x, y, i, t, size) => {
      const hash1 = (x * 73 + y * 37) % 256
      const hash2 = (x * 137 + y * 73) % 256
      return ((x % 8 === 0 || y % 8 === 0) && hash1 > 128) ||
             ((x + y) % 16 === 0 && hash2 > 200)
    }
  },
  'glitch': {
    name: 'Glitch Effect',
    code: 'Digital corruption',
    compiled: (x, y, i, t, size) => {
      const noise = Math.sin(x * 123.456 + y * 789.012) * 1000
      const glitch = Math.floor(noise) % 16
      return ((x % 4 === 0) && (y % 2 === glitch % 2)) ||
             ((y % 8 === 0) && (x % 3 === glitch % 3))
    }
  }
}