import { Dispatch } from 'ketchup-react'
import { Action, chooseWonderAction, maxPlayers, minPlayers, Player, startGameAction, State, structures, wonders } from 'wonders-common'
import Civ from '../Civ/Civ'
import Card from '../Card/Card'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import { ErrorMessage, Field, Form, Formik } from 'formik'

function getDistant<T>(arr: T[], idx: number) {
  switch (idx) {
    case 0: return arr.slice(2, -1)
    case arr.length - 1: return arr.slice(1, -2)
    default: return [...arr.slice(idx + 2), ...arr.slice(0, idx - 1)]
  }
}

function DistantCivs({ players }: { players: Player[] }) {
  return <Row>{players.map(p =>
    <Col key={p.name}>
      <Civ player={p} civStyle='compact' />
    </Col>
  )}</Row>
}

export default function Game({ state, playerName, dispatch }: { state: State, playerName?: string, dispatch: Dispatch<Action> }) {
  const playerIdx: number | undefined = state.players.findIndex(p => p.name === playerName)
  const player: Player | undefined = state.players[playerIdx]
  const started = state.stage !== 'play' ? undefined : {
    left: state.players[(playerIdx + 1) % state.players.length],
    right: state.players[(playerIdx - 1 + state.players.length) % state.players.length],
    distant: getDistant(state.players, playerIdx),
  }

  function isWonderInUse(wonder: string) {
    return state.players.filter(p => p.name !== playerName).map(p => p.wonder).includes(wonder)
  }

  if (!player) {
    return <DistantCivs players={state.players} />
  } else if (started) {
    return <>
      <DistantCivs players={started.distant} />
      <Row>
        <Col><Civ player={started.left} civStyle='neighbor' /></Col>
        <Col>
          <div>{state.age === undefined ? '' : `Age ${state.age + 1} ${state.age % 2 === 0 ? '🔃' : '🔄'}`}</div>
          <div><button>Discards</button></div>
        </Col>
        <Col><Civ player={started.right} civStyle='neighbor' /></Col>
      </Row>
      <Row>
        <Col><Civ player={player} civStyle='player' /></Col>
      </Row>
      <Row>{player.hand?.map(s => structures.get(s)!)?.map(s =>
        <Col>
          <Card structure={s} />
        </Col>
      )}</Row>
    </>
  } else {
    return <>
      <Row>
        <DistantCivs players={state.players} />
      </Row>
      <Row>
        <Formik
          initialValues={{ wonder: player.wonder ?? [...wonders.keys()][0] }}
          validate={values => {
            const errors: Partial<typeof values> = {}
            if (values.wonder.length === 0) {
              errors.wonder = 'Wonder not selected.'
            }
            if (isWonderInUse(values.wonder)) {
              errors.wonder = 'Wonder already in use.'
            }
            return errors
          }}
          onSubmit={({ wonder }) => dispatch(chooseWonderAction(player.name, wonder))}
        >{() => <Form>
          <button type="submit">Choose wonder</button>
          {' '}
          <Field as="select" name="wonder">
            {[...wonders.keys()].map(w =>
              <option key={w} disabled={isWonderInUse(w)}>{w}</option>
            )}
          </Field>
          {' '}
          <ErrorMessage name="wonder" />
        </Form>}
        </Formik>
      </Row>
      <Row>
        <Col><button onClick={() => dispatch(startGameAction(state.players.length))}
          disabled={started !== undefined
            || state.players.length < minPlayers
            || state.players.length > maxPlayers
            || state.players.some(p => p.wonder === undefined)}>
          Start Game
        </button></Col>
      </Row>
      {/* TODO Pick wonder */}
    </>
  }
}
