<script lang="ts">/**
 * An input element which allows to select one or more langauges
 */
import { UIEventSource } from "../../../Logic/UIEventSource"
import all_languages from "../../../assets/language_translations.json"
import { Translation } from "../../i18n/Translation"
import Tr from "../../Base/Tr.svelte"
import Translations from "../../i18n/Translations.js"
import { SearchIcon } from "@rgossiaux/svelte-heroicons/solid"
import Locale from "../../i18n/Locale"

/**
 * Will contain one or more ISO-language codes
 */
export let selectedLanguages: UIEventSource<string[]>
/**
 * The country (countries) that the point lies in.
 * Note that a single place might be claimed by multiple countries
 */
export let countries: Set<string>
let searchValue: UIEventSource<string> = new UIEventSource<string>("")
let searchLC = searchValue.mapD(search => search.toLowerCase())
const knownLanguagecodes = Object.keys(all_languages)
let probableLanguages = []
let isChecked = {}
for (const lng of knownLanguagecodes) {
  const lngInfo = all_languages[lng]
  if (lngInfo._meta?.countries?.some(l => countries.has(l))) {
    probableLanguages.push(lng)
  }
  isChecked[lng] = false
}
let newlyChecked: UIEventSource<string[]> = new UIEventSource<string[]>([])

function update(isChecked: Record<string, boolean>) {
  const currentlyChecked = new Set<string>(selectedLanguages.data)
  const languages: string[] = []
  for (const lng in isChecked) {
    if (isChecked[lng]) {
      languages.push(lng)
      if (!currentlyChecked.has(lng)) {
        newlyChecked.data.push(lng)
        newlyChecked.ping()
      }
    }
  }
  selectedLanguages.setData(languages)
}
function matchesSearch(lng: string, searchLc: string | undefined): boolean {
  if(!searchLc){
    return 
  }
  if(lng.indexOf(searchLc) >= 0){
    return true
  }
  
  const languageInfo = all_languages[lng]
  const native : string = languageInfo[lng]?.toLowerCase()
  if(native?.indexOf(searchLc) >= 0){
    return true
  }
  const current : string = languageInfo[Locale.language.data]?.toLowerCase()
  if(current?.indexOf(searchLc) >= 0){
    return true
  }
  
  return false
}
function onEnter(){
  // we select the first match which is not yet checked
  for (const lng of knownLanguagecodes) {
    if(lng === searchLC.data){
      isChecked[lng] = true
      
      return
    }
  }
  for (const lng of knownLanguagecodes) {
    if(matchesSearch(lng, searchLC.data)){
      isChecked[lng] = true
      return
    }
  }
}
$: {
  update(isChecked)
}
searchValue.addCallback(_ => {
  newlyChecked.setData([])
})
</script>
<form on:submit|preventDefault={() => onEnter()}>

  {#each probableLanguages as lng}

    <label class="no-image-background flex items-center gap-1">
      <input bind:checked={isChecked[lng]} type="checkbox" />
      <Tr t={new Translation(all_languages[lng])} />
      <span class="subtle">({lng})</span>
    </label>

  {/each}

  <label class="block relative neutral-label m-4 mx-16">
    <SearchIcon class="w-6 h-6 absolute right-0" />
    <input bind:value={$searchValue} type="text" />
    <Tr t={Translations.t.general.useSearch} />
  </label>

  <div class="overflow-auto" style="max-height: 25vh">
    {#each knownLanguagecodes as lng}
      {#if (isChecked[lng]) && $newlyChecked.indexOf(lng) < 0 && probableLanguages.indexOf(lng) < 0}
        <label class="no-image-background flex items-center gap-1">
          <input bind:checked={isChecked[lng]} type="checkbox" />
          <Tr t={new Translation(all_languages[lng])} />
          <span class="subtle">({lng})</span>
        </label>

      {/if}
    {/each}

    {#each knownLanguagecodes as lng}
      {#if $searchLC.length > 0 && matchesSearch(lng, $searchLC) && (!isChecked[lng] || $newlyChecked.indexOf(lng) >= 0) && probableLanguages.indexOf(lng) < 0}
        <label class="no-image-background flex items-center gap-1">
          <input bind:checked={isChecked[lng]} type="checkbox" />
          <Tr t={new Translation(all_languages[lng])} />
          <span class="subtle">({lng})</span>
        </label>

      {/if}
    {/each}
  </div>
</form>
