const { createCanvas, loadImage } = (() => { try { return require('canvas') } catch { return {} } })()
const http = require('http')
const fs = require('fs')
const path = require('path')

const W = 2560, H = 1440
const PRESETS = [
  { id: 'glyph', name: 'Glyph', desc: '5x5', tag: 'VERY EASY', icon: 'feather' },
  { id: 'rune', name: 'Rune', desc: '5x5', tag: 'EASY', icon: 'diamond' },
  { id: 'scroll', name: 'Scroll', desc: '9x9', tag: 'MEDIUM', icon: 'compass' },
  { id: 'codex', name: 'Codex', desc: '15x15', tag: 'HARD', icon: 'flame' },
  { id: 'grimoire', name: 'Grimoire', desc: '21x21', tag: 'EXPERT', icon: 'meteor' },
]

function fetchJSON(urlPath) {
  return new Promise((resolve) => {
    http.get(`http://127.0.0.1:8080${urlPath}`, res => {
      if (res.statusCode !== 200) { resolve(null); res.resume(); return }
      let d = ''; res.on('data', c => d += c); res.on('end', () => { try { resolve(JSON.parse(d)) } catch { resolve(null) } })
    }).on('error', () => resolve(null))
  })
}

async function loadIcon(name, size) {
  const dataDir = process.env.DATA_DIR || '/app/data'
  const svgPath = path.join(dataDir, 'icons', `${name}.svg`)
  try {
    let svg = fs.readFileSync(svgPath, 'utf8')
    // set viewBox and size for rendering at target size
    svg = svg.replace(/width="24"/, `width="${size}"`)
    svg = svg.replace(/height="24"/, `height="${size}"`)
    const buf = Buffer.from(svg)
    return await loadImage(buf)
  } catch (e) {
    console.log(`could not load icon ${name}: ${e.message}`)
    return null
  }
}

async function main() {
  console.log('daily image generator starting')
  if (!createCanvas) { console.log('canvas module not available, skipping'); process.exit(0) }

  const today = new Date().toISOString().split('T')[0]
  console.log('generating for', today)
  const dateDisplay = new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }).toUpperCase()

  const grids = await Promise.all(PRESETS.map(async p => {
    const res = await fetchJSON(`/api/puzzles/daily/${today}/${p.id}`)
    return res ? { width: res.puzzle.width, height: res.puzzle.height, cells: res.puzzle.cells } : null
  }))

  // preload icons
  const iconSize = 56
  const icons = await Promise.all(PRESETS.map(p => loadIcon(p.icon, iconSize)))

  const canvas = createCanvas(W, H)
  const ctx = canvas.getContext('2d')

  ctx.fillStyle = '#111111'
  ctx.fillRect(0, 0, W, H)

  const cardW = 400, cardGap = 32, headerH = 240, gridPad = 24, bottomPad = 24
  const gridAreaW = cardW - gridPad * 2, maxGridH = 600

  let tallestCard = headerH + bottomPad
  for (const grid of grids) {
    if (grid) {
      const cellSize = Math.min(gridAreaW / grid.width, maxGridH / grid.height)
      tallestCard = Math.max(tallestCard, headerH + cellSize * grid.height + bottomPad)
    }
  }

  const totalCardsW = 5 * cardW + 4 * cardGap
  const startX = (W - totalCardsW) / 2

  const topRuleH = 3, nameH = 190, dateH = 120, bottomRuleH = 3
  const gapAfterRule = 80, todaysH = 52, gapBeforeCards = 40
  const accentGap = 50, accentH = 3

  const totalContentH = topRuleH + nameH + dateH + bottomRuleH + gapAfterRule + todaysH + gapBeforeCards + tallestCard + accentGap + accentH
  let y = Math.max(0, (H - totalContentH) / 2)

  // top rule
  ctx.fillStyle = '#ededed'
  ctx.fillRect(140, y, W - 280, topRuleH)
  y += topRuleH

  // title
  ctx.fillStyle = '#ededed'
  ctx.font = 'bold 180px serif'
  ctx.textAlign = 'center'
  ctx.fillText('CRUCIVERB', W / 2, y + nameH)
  y += nameH

  // date
  ctx.fillStyle = '#ababab'
  ctx.font = '32px monospace'
  ctx.fillText(dateDisplay, W / 2, y + 55)
  y += dateH

  // bottom rule
  ctx.fillStyle = '#ededed'
  ctx.fillRect(140, y, W - 280, bottomRuleH)
  y += bottomRuleH + gapAfterRule

  // subtitle
  ctx.fillStyle = '#b5b5b5'
  ctx.font = 'italic 52px serif'
  ctx.fillText("Today's puzzles", W / 2, y + todaysH * 0.75)
  y += todaysH + gapBeforeCards

  const cardY = y
  let maxCardBottom = cardY

  // cards
  for (let i = 0; i < 5; i++) {
    const p = PRESETS[i], grid = grids[i]
    const cx = startX + i * (cardW + cardGap)

    let cardH = headerH + bottomPad
    let gridDrawH = 0
    if (grid) {
      const cellSize = Math.min(gridAreaW / grid.width, maxGridH / grid.height)
      gridDrawH = cellSize * grid.height
      cardH = headerH + gridDrawH + bottomPad
    }

    maxCardBottom = Math.max(maxCardBottom, cardY + cardH)

    // card background
    ctx.fillStyle = '#1a1a1a'
    ctx.fillRect(cx, cardY, cardW, cardH)
    ctx.strokeStyle = '#2a2a2a'
    ctx.lineWidth = 1
    ctx.strokeRect(cx, cardY, cardW, cardH)

    // icon
    if (icons[i]) {
      ctx.drawImage(icons[i], cx + cardW / 2 - iconSize / 2, cardY + 28, iconSize, iconSize)
    }

    // preset name
    ctx.fillStyle = '#ededed'
    ctx.font = 'bold 56px serif'
    ctx.textAlign = 'center'
    ctx.fillText(p.name, cx + cardW / 2, cardY + 150)

    // size and tag
    ctx.fillStyle = '#ababab'
    ctx.font = '20px monospace'
    ctx.fillText(`${p.desc}  ${p.tag}`, cx + cardW / 2, cardY + 185)

    // grid
    if (grid) {
      const cellSize = Math.min(gridAreaW / grid.width, maxGridH / grid.height)
      const gridW = cellSize * grid.width, gridH = cellSize * grid.height
      const ox = cx + gridPad + (gridAreaW - gridW) / 2
      const oy = cardY + headerH
      for (let r = 0; r < grid.height; r++) {
        for (let c = 0; c < grid.width; c++) {
          const px = ox + c * cellSize, py = oy + r * cellSize
          ctx.fillStyle = grid.cells[r][c] === 'black' ? '#090909' : '#1e1e1e'
          ctx.fillRect(px, py, cellSize, cellSize)
          ctx.strokeStyle = '#555555'
          ctx.lineWidth = 0.5
          ctx.strokeRect(px, py, cellSize, cellSize)
        }
      }
    }
  }

  // accent line
  ctx.fillStyle = '#d4432f'
  ctx.fillRect(140, maxCardBottom + accentGap, W - 280, accentH)

  // save with today's date and as canonical name
  const buf = canvas.toBuffer('image/jpeg', { quality: 0.85 })
  const dataDir = process.env.DATA_DIR || '/app/data'
  fs.writeFileSync(`${dataDir}/daily-image-${today}.jpg`, buf)
  fs.writeFileSync(`${dataDir}/daily-image.jpg`, buf)
  console.log(`saved daily image for ${today} (${buf.length} bytes)`)
}

main().catch(e => { console.error(e); process.exit(1) })
