import { useState } from 'react'
import './App.css'
import Form from 'react-bootstrap/Form';
import { Badge, Button, ListGroup } from 'react-bootstrap';
import { initials, finales, syllables, tones } from './data';
import { getRandomTones, isEnabled, toggle } from './utils';
import { Found, Syllable, Tone } from './types';
import { strings } from './strings';

const defaultFoundState:Found = {
  allfinales: false,
  allInitiales: false,
  finales: [],
  initiales: [],
  syllables: [],
  toneS: [],
  randomTones: []
}

enum Status {params, plaing, plaied, showlist}

function App() {

  const [ count, setCount ] = useState(10)
  const [ pause, setPause ] = useState(3)

  const [ found, setFound ] = useState(defaultFoundState)

  const onchangepause  = (e: React.ChangeEvent<HTMLInputElement> ) =>  setPause( Number(e.target.value) )
  const onchangecount  = (e: React.ChangeEvent<HTMLInputElement> ) =>  {
    setCount( Number(e.target.value) )
    refreshRandomTones()
  } 
//---------------- to found state
  const toggleAllInitiales = () => {
    let toggled = found.allInitiales ? [] : initials
    let foundSyllables:Syllable[] = syllables.filter( syl =>
      toggled.includes(syl.initiale) && found.finales.includes(syl.finale) )
    let foundTones = tones.filter( t => foundSyllables.some( syl => syl.tones.some( st => st===t.tone) ) )
    let foundRandomTones = getRandomTones( foundTones, count )
    setFound({...found,
        allInitiales: !found.allInitiales,
        initiales: toggled,
        syllables: foundSyllables,
        toneS: foundTones,
        randomTones: foundRandomTones
      })
  }
  const toggleInitialsState = (caption: string) => {
    let toggled = toggle(found.initiales,caption)
    let foundSyllables:Syllable[] = syllables.filter( syl =>
      toggled.includes(syl.initiale) && found.finales.includes(syl.finale) )
    let foundTones = tones.filter( t => foundSyllables.some( syl => syl.tones.some( st => st===t.tone) ) )
    let foundRandomTones = getRandomTones( foundTones, count )
    setFound({...found,
      initiales: toggled,
      syllables: foundSyllables,
      toneS: foundTones,
      randomTones: foundRandomTones
    })
  }

  const toggleAllFinales = () => {
    let toggled = found.allfinales ? [] : finales.map( f => f.finale)
    let foundSyllables:Syllable[] = syllables.filter ( syl =>
      found.initiales.includes( syl.initiale) && toggled.includes( syl.finale ) )
    let foundTones = tones.filter( t => foundSyllables.some( syl => syl.tones.some( st => st===t.tone) ) )
    let foundRandomTones = getRandomTones( foundTones, count )
    setFound({...found,
      allfinales: !found.allfinales,
      finales: toggled,
      syllables: foundSyllables,
      toneS: foundTones,
      randomTones: foundRandomTones
    })
  }
const toggleFinalsState = (caption: string) => {
    let toggled = toggle(found.finales,caption)
    let foundSyllables:Syllable[] = syllables.filter ( syl =>
      found.initiales.includes( syl.initiale) && toggled.includes( syl.finale ) )
    let foundTones = tones.filter( t => foundSyllables.some( syl => syl.tones.some( st => st===t.tone) ) )
    let foundRandomTones = getRandomTones( foundTones, count )
    setFound({...found,
      finales: toggled,
      syllables: foundSyllables,
      toneS: foundTones,
      randomTones: foundRandomTones
    })
  }

  const isFound = ():boolean => found.syllables.length > 0
  const [plaingNo, setPlaingNo ] = useState(0)

// ---- опять по новой
const [ status, setStatus ] = useState(Status.params)

const beginDictation = (): void => {
  refreshRandomTones()
  console.debug(found.randomTones)
  playDictation2(found.randomTones)
}

const playDictation2 = (randomTones: Tone[]) => {
  if ( randomTones.length == 0 ) return
  let audios:HTMLAudioElement[] = []
  randomTones.forEach(element => {
     audios = [...audios, new Audio(`/src/assets/audio/${element.tone}.mp3`) ]
  });
  console.debug(audios)
  if ( audios.length == 0 ) return
  for(let x=0; x<audios.length-1;x++)
  {
    audios[x].onended = () =>  setTimeout( () => { 
      let pno = x+2
      setPlaingNo(pno)
      audios[x+1].play()
    }, 1000*pause ) ;
  }
  audios[audios.length-1].onended = () => setStatus(Status.plaied)
  setStatus(Status.plaing)
  setPlaingNo(1)
  audios[0].play()
}

const renderRandomTones2 = () => {
  return found.randomTones.map( (ton, i) => { return <span key={i}><Badge bg="success" pill>{ton.caption}</Badge>{'  '}</span> })
}

const refresh = () => {
  refreshRandomTones()
  setStatus(Status.params)
}

const refreshRandomTones = () => {
    let foundRandomTones = getRandomTones( found.toneS, count )
    setFound({...found,
      randomTones: foundRandomTones
    })
  }

  return (
    <>
      <h1>Диктант pīnyīn</h1>
      <ListGroup>
      <ListGroup.Item disabled={status != Status.params}>
        <h2>{strings.selectInitiales}</h2>
          <Button variant={found.allInitiales ? "primary" : "outline-primary"}
                  onClick= {()=>toggleAllInitiales()}>
            {found.allInitiales ? strings.unselectAll : strings.selectAll}
          </Button>
           {initials.map( (text, i) => <Button variant={isEnabled(found.initiales, text) ? "primary" : "outline-primary"}
                                          key={i} onClick={()=>toggleInitialsState(text)}>
                                          {text}
                                        </Button>
                            )}
      </ListGroup.Item>
      <ListGroup.Item disabled={status != Status.params}>
        <h2>{strings.selectFinales}</h2>
          <Button variant={found.allfinales ? "success" : "outline-success"}
                  onClick= {toggleAllFinales}>
            {found.allfinales ? strings.unselectAll : strings.selectAll}
          </Button>
          {finales.map( (fin, i) => <Button variant={isEnabled(found.finales, fin.finale) ? "success" : "outline-success"}
                                          key={i} onClick={()=>toggleFinalsState(fin.finale)}>
                                          {fin.caption}
                                        </Button>
                            )}
      </ListGroup.Item>
      <ListGroup.Item disabled={status != Status.params}>
        <h2>{strings.params}</h2>
          <Form.Label>Количество слогов {count}</Form.Label>
          <Form.Range value={count} min={5} max={50} step={5} onChange={onchangecount}/>
          <Form.Label>Пауза между слогами {pause} секунд</Form.Label>
          <Form.Range value={pause} min={1} max={10} step={1} onChange={onchangepause}/>
      </ListGroup.Item>
      <ListGroup.Item>
        { status == Status.params &&
          <>
        Выбрано {found.initiales.length} инициалей,  {found.finales.length}  финалей, найдено {found.syllables.length} слогов, { found.toneS.length } тонов , 
        <br/>
        <Button variant={isFound() ? "success" : "secondary"} size="lg"  onClick={()=>beginDictation()} disabled={!isFound()}>
            {isFound() ? "Начать диктант!" : "Выберите инициали и финали" }
          </Button>
          </>
        }
        {
          status == Status.plaing &&
          <h1>Воспроизводится...{plaingNo}</h1>
        }
        {
          status == Status.plaied &&
          <Button variant="success" onClick={()=>setStatus(Status.showlist)}>Показать слоги</Button>
        }
        {
          status == Status.showlist &&
          <>
            <div>{renderRandomTones2()}</div>
            <br/>
            <Button variant="success" onClick={()=>refresh()}>В начало</Button>
          </>
        }
      </ListGroup.Item>
      </ListGroup>
    </>
  )
}

export default App

