import { ContextI } from '../ContextI'
import { StateI } from './StateI'
import { OutlineFilter } from '@pixi/filter-outline'
import * as PIXI from 'pixi.js'
import { GameState } from './Game'
import { SpriteInstance } from '../shared/sprites'
import { animals } from '../data/animals'
import { segments } from '../shared/segments'
import { bodyTextStyle, buttonBlurStyle, buttonHoverStyle } from '../styles'

interface MenuItem {
  text: PIXI.Text,
}

export function MenuState(ctx: ContextI): StateI {
  let container = new PIXI.Container()
  let scaryBoi = new SpriteInstance('ui.menu.decorative.scary-boi.0')
  let scaryBun = new SpriteInstance('ui.menu.decorative.scary-bun.0')

  container.addChild(scaryBoi.container)
  container.addChild(scaryBun.container)

  let logoSprite: SpriteInstance = new SpriteInstance('ui.menu.logo.default.0')
  logoSprite.container.scale.set(3, 3)
  container.addChild(logoSprite.container)

  // Animal Selections
  let animalSprites: SpriteInstance[] = Object.keys(animals).map(v => {
    let s = new SpriteInstance(`${v}.animal.stand.west.0`)
    s.container.interactive = true
    s.container.on('pointerdown', () => {
      if (selectedAnimalSprite) {
        selectedAnimalSprite.container.filters = []
      }
      selectedAnimalName = v
      selectedText.text = v
      selectedAnimalSprite = s
      selectedAnimalSprite.container.filters = [
        new OutlineFilter(2, 0x99ff99)
      ]
    })
    s.container.scale.set(3, 3)
    container.addChild(s.container)
    return s
  })
  let animalIndex = Math.floor(Math.random() * Object.keys(animals).length)
  let selectedAnimalName = Object.keys(animals)[animalIndex]
  let selectedAnimalSprite: SpriteInstance = animalSprites[animalIndex]
  selectedAnimalSprite.container.filters = [
    new OutlineFilter(2, 0x99ff99)
  ]

  // Segment Selections
  let segmentItems: PIXI.Text[] = Object.keys(segments).map(v => {
    let s = new PIXI.Text(v, new PIXI.TextStyle({
      fontFamily: 'Arial',
      fontSize: 30,
      fill: ['#ffffff'],
    }))
    s.interactive = true
    s.on('pointerdown', () => {
      selectedSegmentName = v
      selectedSegmentItem.filters = []
      selectedSegmentItem.style.fill = ['#ffffff']
      selectedSegmentItem = s
      selectedSegmentItem.filters = [
        new OutlineFilter(2, 0x99ff99)
      ]
      selectedSegmentItem.style.fill = ['#000000']
    })
    container.addChild(s)
    return s
  })
  let selectedSegmentItem: PIXI.Text = segmentItems.find(v=>v.text==='world') ?? segmentItems[0]
  let selectedSegmentName = 'world'
  selectedSegmentItem.filters = [
    new OutlineFilter(2, 0x99ff99)
  ]
  selectedSegmentItem.style.fill = ['#000000']

  let selectedText = new PIXI.Text(selectedAnimalName, bodyTextStyle())

  let text = new PIXI.Text('Global Game Jam 2022', new PIXI.TextStyle({
    fontFamily: 'Arial',
    fontSize: 16,
    dropShadow: true,
    fill: ['#ffffff'],
    stroke: '#000000',
  }))

  let menuItems: PIXI.Text[] = []

  {
    let el = new PIXI.Text('Begin the Hunt', buttonBlurStyle())
    el.interactive = true
    el.on('pointerdown', () => {
      ctx.push(GameState(ctx, selectedAnimalName, selectedSegmentName))
    })
    el.on('pointerover', () => {
      el.style = buttonHoverStyle()
    })
    el.on('pointerout', () => {
      el.style = buttonHoverStyle()
    })
    menuItems.push(el)
    container.addChild(el)
  }

  container.addChild(text)
  container.addChild(selectedText)

  let enter = () => {
    console.log('MenuState.enter')
    ctx.app.stage.addChild(container)
  }
  let leave = () => {
    console.log('MenuState.leave')
    ctx.app.stage.removeChild(container)
  }
  let update = (delta: number) => {
    let yPos = logoSprite.height * 2
    // Eh... this isn't too expensive.
    let maxWidth = 0
    let maxX = 0

    logoSprite.container.x = ctx.app.view.width / 2
    logoSprite.container.y = yPos
    yPos += logoSprite.height + 32

    text.x = ctx.app.view.width / 2 - text.width / 2
    text.y = yPos
    yPos += text.height + 32
    
    //
    selectedText.y = yPos
    selectedText.x = ctx.app.view.width / 2 - selectedText.width / 2
    yPos += selectedText.height

    // draw our animal selections.
    let spritesWidth = animalSprites.reduce((p,v)=>{
      return p + v.container.width
    }, 0)
    let xPos = ctx.app.view.width / 2 - spritesWidth*0.7
    for (let s of animalSprites) {
      xPos += s.container.width
      s.container.x = xPos
      s.container.y = yPos
    }
    yPos += animalSprites[0].container.height + 32

    // Draw our segment selections.
    for (let item of segmentItems) {
      item.x = ctx.app.view.width / 2 - item.width / 2
      if (item.width > maxWidth) {
        maxWidth = item.width
      }
      item.y = yPos
      yPos += item.height + 8
    }
    yPos += 32

    // Draw rest of the garbage.
    for (let item of menuItems) {
      item.x = ctx.app.view.width / 2 - item.width / 2
      if (item.width > maxWidth) {
        maxWidth = item.width
      }
      item.y = yPos
      yPos += item.height + 8
    }
    scaryBoi.container.y = 0
    scaryBoi.container.x = ctx.app.view.width - scaryBoi.container.width/3
    scaryBun.container.y = 0
    scaryBun.container.x = -scaryBun.container.width/2
  }

  return {
    enter,
    leave,
    update,
  }
}
