import Cell from '../components/Cell'
import { connect } from 'react-redux'
import { compose, withState, withHandlers } from 'recompose'
import {
  setAsync as setWallsAsync,
  clearOneAsync as clearOneWallsAsync,
} from '../redux/actions/walls'
import {
  setAsync as setTeleporterAsync,
  readAsync as readTeleporterAsync,
  clearOneAsync as clearOneTeleporterAsync,
} from '../redux/actions/teleporter'
import {
  setAsync as setFloorAsync,
  clearOneAsync as clearOneFloorAsync,
} from '../redux/actions/floor'
import {
  setAsync as setEncountersAsync,
  clearOneAsync as clearOneEncountersAsync,
} from '../redux/actions/encounters'
import { setAsync as setPartyAgentAsync } from '../redux/actions/partyAgent'

import DungeonEditor from './DungeonEditor'
import { pregeneratedParty } from '../shared/settings'

const DMInterface = ({
  readTeleporterAsync,
  clearOneWallsAsync,
  clearOneFloorAsync,
  clearOneEncountersAsync,
  setPartyAgentAsync,
  dungeons,
  encounters,
  palette,
  setPalette,
  teleporter,
  type,
  setType,
  id,
  setId,
  floor,
  setFloorAsync,
  setEncountersAsync,
  walls,
  setWallsAsync,
  selectCell,
  setSelectedCells,
  clearCells,
  selectedCells,
  editor,
  selectedStartCell,
  setSelectedStartCell,
  selectedEndCell,
  setSelectedEndCell,
  setTeleporterAsync,
  destination,
  setDestination,
  setDestinationOf,
}) => (
  <div>
    <DungeonEditor />
    <div
      onClick={() => {
        const xDimensions = dungeons[editor.dungeon].dimensions.x
        const yDimensions = dungeons[editor.dungeon].dimensions.y
        for (let x = 0; x < xDimensions; x++) {
          setWallsAsync({
            x,
            y: 0,
            z: editor.activeFloor,
            dungeon: editor.dungeon,
            cardinal: `s`,
            type: 1,
          })
          setWallsAsync({
            x,
            y: yDimensions - 1,
            z: editor.activeFloor,
            dungeon: editor.dungeon,
            cardinal: `n`,
            type: 1,
          })
        }
        for (let y = 0; y < yDimensions; y++) {
          setWallsAsync({
            x: 0,
            y,
            z: editor.activeFloor,
            dungeon: editor.dungeon,
            cardinal: `w`,
            type: 1,
          })
          setWallsAsync({
            x: xDimensions - 1,
            y,
            z: editor.activeFloor,
            dungeon: editor.dungeon,
            cardinal: `e`,
            type: 1,
          })
        }
      }}
    >
      wrap/unwrap walls
    </div>
    <div
      onClick={() => {
        const xDimensions = dungeons[editor.dungeon].dimensions.x
        const yDimensions = dungeons[editor.dungeon].dimensions.y
        for (let y = 0; y < yDimensions; y++) {
          for (let x = 0; x < xDimensions; x++) {
            setFloorAsync({
              x,
              y,
              z: editor.activeFloor,
              dungeon: editor.dungeon,

              type: 2,
            })
          }
        }
      }}
    >
      lay/remove floor
    </div>
    <div
      onClick={() => {
        const xDimensions = dungeons[editor.dungeon].dimensions.x
        const yDimensions = dungeons[editor.dungeon].dimensions.y
        for (let y = 0; y < yDimensions; y++) {
          for (let x = 0; x < xDimensions; x++) {
            setFloorAsync({
              x,
              y,
              z: editor.activeFloor,
              dungeon: editor.dungeon,

              type: 1,
            })
          }
        }
      }}
    >
      fill with bricks
    </div>

    <div onClick={() => setPartyAgentAsync({ party: pregeneratedParty })}>pregen party</div>
    <div style={{ position: `fixed`, right: 0, bottom: 0 }}>
      f1:rock, f2: descent, f3: barrel, f4: brazier, f5: watercube, f6: water surface
    </div>
    <div style={{ position: `fixed`, right: 0, bottom: `1rem` }}>
      f1:wall, f2: stair, f3: door, f4: secret door, f5: window
    </div>
    <div style={{ position: `fixed`, right: 0 }}>
      <button
        onClick={() => {
          if (selectedCells.length > 0) {
            if (palette === `floor`) {
              selectedCells.forEach(cell => {
                const { x, y, z, dungeon } = cell
                setFloorAsync({ x, y, z, dungeon, type })
              })
            }
            if (palette === `encounters`) {
              selectedCells.forEach(cell => {
                const { x, y, z, dungeon } = cell
                setEncountersAsync({ x, y, z, dungeon, type, id })
              })
            }
            if (palette === `walls`) {
              const { x: xs, y: ys, z: zs, dungeon } = selectedStartCell
              const { x: xe, y: ye, z: ze } = selectedEndCell
              for (let z = zs; z <= ze; z++) {
                for (let x = xs; x <= xe; x++) {
                  setWallsAsync({
                    x,
                    y: ys,
                    z,
                    dungeon,
                    cardinal: `s`,
                    type,
                  })
                  setWallsAsync({
                    x,
                    y: ys - 1,
                    z,
                    dungeon,
                    cardinal: `n`,
                    type,
                  })
                  setWallsAsync({
                    x,
                    y: ye + 1,
                    z,
                    dungeon,
                    cardinal: `s`,
                    type,
                  })
                  setWallsAsync({
                    x,
                    y: ye,
                    z,
                    dungeon,
                    cardinal: `n`,
                    type,
                  })
                }
                for (let y = ys; y <= ye; y++) {
                  setWallsAsync({
                    x: xs,
                    y,
                    z,
                    dungeon,
                    cardinal: `w`,
                    type,
                  })
                  setWallsAsync({
                    x: xs - 1,
                    y,
                    z,
                    dungeon,
                    cardinal: `e`,
                    type,
                  })
                  setWallsAsync({
                    x: xe + 1,
                    y,
                    z,
                    dungeon,
                    cardinal: `w`,
                    type,
                  })
                  setWallsAsync({
                    x: xe,
                    y,
                    z,
                    dungeon,
                    cardinal: `e`,
                    type,
                  })
                }
              }
              //setEncountersAsync({ x, y, z, dungeon, type, id })
            }
          }
        }}
      >
        fill
      </button>
      <button
        onClick={() => {
          if (selectedCells.length > 0) {
            selectedCells.forEach(cell => {
              clearOneEncountersAsync({ x: cell.x, y: cell.y, z: cell.z, dungeon: cell.dungeon })
              clearOneFloorAsync({ x: cell.x, y: cell.y, z: cell.z, dungeon: cell.dungeon })
              clearOneWallsAsync({ x: cell.x, y: cell.y, z: cell.z, dungeon: cell.dungeon })
            })
          }
        }}
      >
        clear selected
      </button>
      {[`walls`, `floor`, `encounters`, `select`, `teleporter`].map(p => (
        <div
          key={p}
          style={{ fontWeight: palette === p ? `bold` : `normal` }}
          onClick={() => setPalette(p)}
        >
          p: {p}
        </div>
      ))}

      {[1, 2, 3, 4, 5, 6].map(t => (
        <div
          key={t}
          style={{ fontWeight: type === t ? `bold` : `normal` }}
          onClick={() => setType(t)}
        >
          t: {t}
        </div>
      ))}

      {palette === `encounters` && <input value={id} onChange={e => setId(e.target.value)} />}
      {palette === `teleporter` && (
        <div>
          {/* <button onClick={() => readTeleporterAsync()}> readTeleporterAsync </button> */}
          <input
            style={{ width: `2rem` }}
            type={`number`}
            value={destination.x}
            onChange={async e => {
              console.log({ ...destination, x: parseInt(e.target.value) })
              setDestination({ ...destination, x: parseInt(e.target.value) })
            }}
          />
          <input
            style={{ width: `2rem` }}
            type={`number`}
            value={destination.y}
            onChange={async e => setDestination({ ...destination, y: parseInt(e.target.value) })}
          />
          <input
            style={{ width: `2rem` }}
            type={`number`}
            value={destination.z}
            onChange={async e => setDestination({ ...destination, z: parseInt(e.target.value) })}
          />
          <input
            style={{ width: `5rem` }}
            type={`text`}
            value={destination.dungeon}
            onChange={async e => setDestination({ ...destination, dungeon: e.target.value })}
          />
        </div>
      )}
    </div>
    <div {...{ className: `dungeons` }}>
      {/* {JSON.stringify(selectedCells)}
      {JSON.stringify(selectedStartCell)}
      {JSON.stringify(selectedEndCell)} */}
      {Object.keys(dungeons).map(
        dungeon =>
          editor.dungeon === dungeon && (
            <div
              {...{
                className: `dungeon`,
                style: { display: `flex`, flexWrap: `wrap`, marginRight: `1rem` },
              }}
              key={dungeon}
            >
              {dungeon}
              {new Array(dungeons[dungeon].dimensions.z).fill(null).map((_, z) => (
                <div
                  {...{
                    className: `zlevel`,
                    style: { marginRight: `1rem` },
                  }}
                  key={z}
                >
                  {z}
                  {new Array(dungeons[dungeon].dimensions.y).fill(null).map((_, yr) => {
                    const y = dungeons[dungeon].dimensions.y - yr - 1
                    return (
                      <div key={y} {...{ className: `row`, style: { display: `flex` } }}>
                        {new Array(dungeons[dungeon].dimensions.x).fill(null).map((_, x) => (
                          <Cell
                            onClick={(e, containerRef) => {
                              if (palette === `select`) {
                                if (selectedCells.length !== 1) {
                                  console.log(`1`)
                                  setSelectedStartCell({
                                    x,
                                    y,
                                    z,
                                    dungeon,
                                  })
                                  setSelectedEndCell({
                                    x,
                                    y,
                                    z,
                                    dungeon,
                                  })
                                  setSelectedCells([
                                    {
                                      x,
                                      y,
                                      z,
                                      dungeon,
                                    },
                                  ])
                                } else if (
                                  selectedCells[0].x === x &&
                                  selectedCells[0].y === y &&
                                  selectedCells[0].z === z
                                ) {
                                  clearCells()
                                  console.log(`2`)
                                } else {
                                  console.log(`3`)
                                  setSelectedEndCell({
                                    x,
                                    y,
                                    z,
                                    dungeon,
                                  })
                                  clearCells()
                                  for (let zi = selectedCells[0].z; zi <= z; zi++) {
                                    for (let yi = selectedCells[0].y; yi <= y; yi++) {
                                      for (let xi = selectedCells[0].x; xi <= x; xi++) {
                                        selectCell({ x: xi, y: yi, z: zi, dungeon })
                                      }
                                    }
                                  }
                                }
                              }
                              if (palette === `floor`) {
                                setFloorAsync({ x, y, z, dungeon, type })
                              }
                              if (palette === `teleporter`) {
                                setTeleporterAsync({ x, y, z, dungeon, type, destination })
                              }
                              if (palette === `encounters`) {
                                setEncountersAsync({ x, y, z, dungeon, type, id })
                              }
                              if (palette === `walls`) {
                                const mouseX =
                                  e.pageX -
                                  window.pageXOffset -
                                  containerRef.current.getBoundingClientRect().x
                                const mouseY =
                                  e.pageY -
                                  window.pageYOffset -
                                  containerRef.current.getBoundingClientRect().y

                                const xRatio =
                                  mouseX / containerRef.current.getBoundingClientRect().height
                                const yRatio =
                                  mouseY / containerRef.current.getBoundingClientRect().width
                                let cardinal
                                if (xRatio > yRatio === false && xRatio + yRatio > 1 === true)
                                  cardinal = `s`
                                if (xRatio > yRatio === true && xRatio + yRatio > 1 === true)
                                  cardinal = `e`
                                if (xRatio > yRatio === true && xRatio + yRatio > 1 === false)
                                  cardinal = `n`
                                if (xRatio > yRatio === false && xRatio + yRatio > 1 === false)
                                  cardinal = `w`
                                console.log(containerRef.current.getBoundingClientRect())
                                console.log(`e.pageX: `, e.pageX)
                                console.log(`e.pageY: `, e.pageY)
                                console.log(`mouseX: `, mouseX)
                                console.log(`mouseY: `, mouseY)
                                console.log(`window.pageYOffset: `, window.pageYOffset)
                                console.log(`cardinal: `, cardinal)
                                const getParams = ({ cardinal, ...props }) => ({
                                  x,
                                  y,
                                  z,
                                  dungeon,
                                  type,
                                  cardinal,
                                  ...props,
                                })
                                if (type === 1 || type === 3 || type === 4 || type === 5) {
                                  if (cardinal === `n`) {
                                    setWallsAsync(getParams({ cardinal: `n` }))
                                    if (y !== dungeons[dungeon].dimensions.y)
                                      setWallsAsync(getParams({ cardinal: `s`, y: y + 1 }))
                                  }
                                  if (cardinal === `e`) {
                                    setWallsAsync(getParams({ cardinal: `e` }))
                                    if (x !== dungeons[dungeon].dimensions.x)
                                      setWallsAsync(getParams({ cardinal: `w`, x: x + 1 }))
                                  }
                                  if (cardinal === `w`) {
                                    setWallsAsync(getParams({ cardinal: `w` }))
                                    if (x !== 0)
                                      setWallsAsync(getParams({ cardinal: `e`, x: x - 1 }))
                                  }
                                  if (cardinal === `s`) {
                                    setWallsAsync(getParams({ cardinal: `s` }))
                                    if (y !== 0)
                                      setWallsAsync(getParams({ cardinal: `n`, y: y - 1 }))
                                  }
                                }
                                {
                                  /* if (type === 3 || type === 4) {
                                    if (cardinal === `n`) {
                                      setWallsAsync(getParams({ cardinal: `n` }))
                                    }
                                    if (cardinal === `e`) {
                                      setWallsAsync(getParams({ cardinal: `e` }))
                                    }
                                    if (cardinal === `w`) {
                                      setWallsAsync(getParams({ cardinal: `w` }))
                                    }
                                    if (cardinal === `s`) {
                                      setWallsAsync(getParams({ cardinal: `s` }))
                                    }
                                  } */
                                }
                                if (type === 2) {
                                  if (cardinal === `n`) {
                                    setWallsAsync(getParams({ cardinal: `n` }))
                                    if (y !== dungeons[dungeon].dimensions.y)
                                      setWallsAsync(getParams({ cardinal: `s`, y: y + 1, type: 1 }))
                                  }
                                  if (cardinal === `e`) {
                                    setWallsAsync(getParams({ cardinal: `e` }))
                                    if (x !== dungeons[dungeon].dimensions.x)
                                      setWallsAsync(getParams({ cardinal: `w`, x: x + 1, type: 1 }))
                                  }
                                  if (cardinal === `w`) {
                                    setWallsAsync(getParams({ cardinal: `w` }))
                                    if (x !== 0)
                                      setWallsAsync(getParams({ cardinal: `e`, x: x - 1, type: 1 }))
                                  }
                                  if (cardinal === `s`) {
                                    setWallsAsync(getParams({ cardinal: `s` }))
                                    if (y !== 0)
                                      setWallsAsync(getParams({ cardinal: `n`, y: y - 1, type: 1 }))
                                  }
                                }
                              }
                            }}
                            key={x}
                            {...{
                              dmView: true,
                              x,
                              y,
                              isSelected: selectedCells.find(
                                cell =>
                                  cell.x === x &&
                                  cell.y === y &&
                                  cell.z === z &&
                                  cell.dungeon === dungeon
                              ),
                              floor: floor[dungeon] ? floor[dungeon][`x${x}y${y}z${z}`] : 0,
                              encounters: encounters[dungeon]
                                ? encounters[dungeon][`x${x}y${y}z${z}`]
                                : {},
                              teleporter: teleporter[dungeon]
                                ? teleporter[dungeon][`x${x}y${y}z${z}`]
                                : {},
                              walls: walls[dungeon]
                                ? walls[dungeon][`x${x}y${y}z${z}`]
                                  ? walls[dungeon][`x${x}y${y}z${z}`]
                                  : {}
                                : {},
                            }}
                          />
                        ))}
                      </div>
                    )
                  })}
                </div>
              ))}
            </div>
          )
      )}
    </div>
  </div>
)

const mapStateToProps = state => ({
  walls: state.walls,
  floor: state.floor,
  encounters: state.encounters,
  dungeons: state.dungeons,
  editor: state.editor,
  teleporter: state.teleporter,
})

const enhance = compose(
  withState(`palette`, `setPalette`, `walls`),
  withState(`type`, `setType`, 1),
  withState(`id`, `setId`, `eid0`),
  withState(`selectedCells`, `setSelectedCells`, []),
  withState(`selectedStartCell`, `setSelectedStartCell`, {}),
  withState(`selectedEndCell`, `setSelectedEndCell`, {}),
  withState(`destination`, `setDestination`, { x: 0, y: 0, z: 0, dungeon: `crypt` }),
  withHandlers({
    selectCell: ({ setSelectedCells }) => ({ x, y, z, dungeon }) => {
      setSelectedCells(v => [...v, { x, y, z, dungeon }])
    },
    clearCells: ({ setSelectedCells }) => () => setSelectedCells([]),
    setDestinationOf: ({ setDestination }) => (e, param) => {
      setDestination(v => ({ ...v, [param]: e.target.value }))
    },
  }),
  withHandlers({}),
  connect(
    mapStateToProps,
    {
      setWallsAsync,
      setFloorAsync,
      setEncountersAsync,
      setPartyAgentAsync,
      clearOneWallsAsync,
      clearOneFloorAsync,
      clearOneEncountersAsync,
      setTeleporterAsync,
      clearOneTeleporterAsync,
      readTeleporterAsync,
    }
  )
)

export default enhance(DMInterface)
