import { useState } from 'preact/hooks'
import './gcf.css'
import { gcf } from './lib'
import type { JSX } from 'preact'

type SolutionRow = [Number, Number, Number, Number]
type SolutionKey = Array<SolutionRow>
type SolutionParams = {
  rows : SolutionKey
}

function Solution({rows}:SolutionParams) {
  const colors = [
    "red",
    "blue",
    "green",
    "brown",
    "purple",
    "orange"
  ]
  const displayRow = (row : SolutionRow, index : number) => {
    let range : number[] = [0, 1, 2]
    const styles = range.map((i)=>{return `padding:3px;color:white;background:${colors[(i+index)%colors.length]}`})
    return <p>
      <span style={styles[0]}>{row[0]}</span>&nbsp;&divide;&nbsp;<span style={styles[1]}>{row[2]}</span>&nbsp;=&nbsp;{row[1]}&nbsp;R&nbsp;<span style={styles[2]}>{row[3]}</span>
    </p>
  }

  return <div className="solution text-center" data-bs-theme="light">
    {rows.map(displayRow)}
  </div>
}


export function GCF() {
  // choose number between 2 and max inclusive
  const getRandomInt = (max : number) : number => Math.floor(Math.random() * (max - 1) + 2)

  const chooseFactorsRandom = () : [number, number] => [ getRandomInt(200), getRandomInt(200) ]

  const _chooseMultiplesOf = (f : number) : [number, number] => {
    const max = Math.floor(200 / f)
    return [ f * getRandomInt(max), f * getRandomInt(max) ]
  }

  const chooseMultiplesOf = (f : number) : () => [ number, number ] => {
    return () => _chooseMultiplesOf(f)
  }

  const chooseMultiples = () : [number, number] => {
    const f = getRandomInt(50)
    return _chooseMultiplesOf(f)
  }

  const chooseFactors = () : [number, number] => {
    const probabilities : Array<[number, () => [number, number]]>= [
      [ 0.2, chooseFactorsRandom ],
      [ 0.2, chooseMultiples ],
      [ 0.2, chooseMultiplesOf(3) ],
      [ 0.2, chooseMultiplesOf(7) ],
      [ 0.1, chooseMultiplesOf(11) ],
      [ 0.1, chooseMultiplesOf(17) ],
    ]
    const r = Math.random()
    var i = 0, accum = 0
    for (i = 0; i < probabilities.length; i++) {
      console.log([r, i, accum, probabilities[i]])
      if ((r > accum) && (r <= accum + probabilities[i][0])) break
      accum += probabilities[i][0]
    }
    if (i >= probabilities.length) i = probabilities.length - 1
    return probabilities[i][1]()
  }

  const getSolution = (a : number, b : number) : SolutionKey => {
    var result : SolutionKey = [ ]
    if (b > a) {
      var t = b
      b = a
      a = t
    }
    while (b != 0) {
      result.push([ a, Math.floor(a / b), b, a % b ])
      var t = a % b
      a = b
      b = t
    }
    return result
  }

  const doCheck = (e : Event) : void => {
    e.preventDefault()
    const rightAnswer = gcf(factors[0], factors[1])
    const yourAnswer = (document.getElementById("inlineFormInputResponse") as HTMLInputElement).value
    if (rightAnswer == Number(yourAnswer)) {
      setCorrect(true)
      setFeedback(true)
    } else {
      setFeedback(true)
    }
    
  }

  const doNext = (e : Event) : void => {
    e.preventDefault()
    setFeedback(false)
    setCorrect(false)
    setFactors(chooseFactors())
    setSolution(null)
    document.forms[0].reset()
  }

  const doSolution = (e : Event) : void => {
    e.preventDefault()
    if (solution === null) {
      var answerBox = document.getElementById("inlineFormInputResponse") as HTMLInputElement
      answerBox.value = String(gcf(factors[0], factors[1]))
      setSolution(<Solution rows={getSolution(factors[0], factors[1])} />)
      setCorrect(true)
      //setFeedback(true)
    } else {
      setSolution(null)
    }
  }

  const [factors, setFactors] = useState(chooseFactors())

  const [correct, setCorrect] = useState(false)
  const [feedback, setFeedback] = useState(false)
  const [solution, setSolution] = useState<JSX.Element|null>(null)

  return (
      <div className="px-4 py-5 my-5 text-center">
        <h1 className="my-5">Greatest Common Factor Practice</h1>
        <p className="fs-3">What is the greatest common factor of <mark>{factors[0]}</mark> and <mark>{factors[1]}</mark>?</p>
        <form className="row row-cols-lg-auto g-3 align-items-center justify-content-center">
          <div className="col-12">
            <label className="visually-hidden" for="inlineFormInputResponse">Response</label>
            <div className="input-group">
              <input type="text" size={3} autocomplete="off" className="form-control text-center" id="inlineFormInputResponse" />
            </div>
          </div>
          <div className="col-12">
            <button type="submit" onClick={correct ? doNext : doCheck} className="btn btn-primary">{correct ? "Next" : "Check"}</button>
            <button type="submit" onClick={doSolution} className="ms-2 btn btn-secondary">{solution !== null ? "Hide" : "Solve"}</button>
          </div>
        </form>
        <div className={feedback ? "visible" : "invisible"}>
          <div className={correct ? "alert alert-success m-4" : "alert alert-danger m-4"}>{correct ? "Correct" : "Try again!"}</div>
        </div>
        {solution !== null ? solution : <></>}
      </div>
  )
}
