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

type SolutionParams = {
  factors : [ number, number ],
  gcf : number,
  result : number
}

function Solution({factors, gcf, result}:SolutionParams) {
  const multipliers = [
    Math.floor(result/factors[0]),
    Math.floor(result/factors[1]),
  ]
  return <div className="solution text-center" data-bs-theme="light">
    <p>GCF({factors[0]},&nbsp;{factors[1]})&nbsp;=&nbsp;{gcf}</p>
    <p>{factors[0]}&nbsp;&times;&nbsp;{factors[1]}&nbsp;&divide;&nbsp;{gcf}&nbsp;=&nbsp;{result}</p>
    <p>{factors[0]}&nbsp;&times;&nbsp;{multipliers[0]}&nbsp;=&nbsp;{result}</p>
    <p>{factors[1]}&nbsp;&times;&nbsp;{multipliers[1]}&nbsp;=&nbsp;{result}</p>
  </div>
}


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

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

  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(20)
    return _chooseMultiplesOf(f)
  }

  const chooseFactors = () : [number, number] => {
    const probabilities : Array<[number, () => [number, number]]>= [
      [ 0.5, chooseFactorsRandom ],
      [ 0.5, chooseMultiples ],
    ]
    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 doCheck = (e : Event) : void => {
    e.preventDefault()
    const rightAnswer = Math.floor(factors[0] / gcf(factors[0], factors[1])) * 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
      const theGCF = gcf(factors[0], factors[1])
      const rightAnswer = Math.floor(factors[0] / theGCF) * factors[1]
      answerBox.value = String(rightAnswer)
      setSolution(<Solution factors={factors} gcf={theGCF} result={rightAnswer} />)
      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 d-none d-sm-block">Least Common Multiple Practice</h1>
        <p className="fs-3">What is the least common multiple 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="number" size={3} autocomplete="off" className="form-control text-center no-arrows" 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>
  )
}
