<script>
 import {
     Button,
     Card,
     CardBody,
     CardHeader,
     CardText,
     Icon,
     ListGroup,
     ListGroupItem,
     Progress,
     Spinner,
 } from 'sveltestrap';

 import { blake2b } from 'hash-wasm';

 import { my } from '../stores/my.js';

 import DateFormat from './DateFormat.svelte';
 import FlagKey from './FlagKey.svelte';
 import FlagMCQ from './FlagMCQ.svelte';

 export let exercice = { };
 export let flags = [];

 export let refresh_my;
 export let refresh_teams;

 function waitDiff(i) {
     refresh_my((my) => {
         if (my && my.exercices[exercice.id].solved_time != exercice.solved_time) {
             submitInProgress = false;
             refresh_teams();
         } else if (i > 0) {
             setTimeout(waitDiff, 450, i-1);
         } else {
             timeouted = true;
             submitInProgress = false;
         }
     })
 }

 export let forcesolved = false;
 let responses = { };
 async function submitFlags() {
     submitInProgress = true;
     sberr = "";
     message = "";

     if ($my && $my.team_id === 0) {
         let allGoodResponse = true;
         for (const f in flags) {
             const flag = flags[f];

             let soluce = "";
             if (flag.type == "mcq") {
                 for (const c in flag.choices) {
                     soluce += responses.mcqs[c] ? "t" : "f";
                 }
             } else {
                 soluce = responses.flags[flag.id];
             }

             if (flag.ignore_case) {
                 soluce = soluce.toLowerCase();
             }

             if (flag.validator_regexp) {
                 let re = new RegExp(flag.validator_regexp, flag.ignore_case?'i':'');
                 soluce = soluce.match(re).slice(1).join("+");
             }

             if (await blake2b(soluce) == flag.soluce) {
                 flags[f].found = new Date();
             } else if (!flag.found) {
                 allGoodResponse = false;
             }
             flags = flags;
         }

         if (allGoodResponse) {
             forcesolved = true;
         }

         if (exercice.tries) {
             exercice.tries += 1;
         } else {
             exercice.tries = 1;
         }
         exercice.solved_time = new Date();
         exercice = exercice;

         submitInProgress = false;
     } else {
         const response = await fetch(
             "submit/" + exercice.id,
             {
                 method: "POST",
                 headers: {'Accept': 'application/json'},
                 body: JSON.stringify(responses),
             }
         )

         if (response.status < 300) {
             const data = await response.json();
	     messageClass = 'text-success';
	     message = data.errmsg;
             waitDiff(20);
         } else {
             submitInProgress = false;

	     messageClass = 'text-danger';

             let data = "";
             try {
                 data = await response.json();
             } catch(e) {
                 data = null;
             }

	     if (data && data.errmsg)
	         message = data.errmsg;
	     if (response.statys != 402)
	         sberr = "Oups !";
         }
     }
 }

 function resetResponses() {
     responses = {
         flags: { },
         mcqs: { },
         justifications: { },
     };
 }

 let last_exercice = null;
 $: {
     if (!last_exercice || last_exercice != exercice.id) {
         last_exercice = exercice.id;
         resetResponses()
     }
 }

 let sberr = "";
 let message = "";
 let messageClass = "text-danger";
 let timeouted = false;
 let submitInProgress = false;
</script>

<Card class="border-danger mb-2">
    <CardHeader class="bg-danger text-light">
        <Icon name="flag-fill" />
        Faire son rapport
    </CardHeader>
    {#if exercice.flags.length != exercice.nb_flags}
        <Progress
            value={exercice.flags.length}
            max={exercice.nb_flags}
            class="rounded-0"
            barClassName="text-light"
        >
            {exercice.flags.length}/{exercice.nb_flags}
        </Progress>
    {/if}
    {#if exercice.tries || exercice.solved_time || exercice.submitted || sberr || timeouted}
        <ListGroup class="border-dark">
            {#if exercice.solved_time || exercice.tries}
                <ListGroupItem class="text-warning rounded-0">
                    {#if exercice.tries > 0}{exercice.tries} {exercice.tries==1?"tentative effectuée":"tentatives effectuées"}.{/if}
                    Dernière solution envoyée à <DateFormat date={exercice.solved_time} />.
                </ListGroupItem>
            {/if}
            {#if exercice.solve_dist}
                <ListGroupItem class="rounded-0">
                    {exercice.solve_dist} {exercice.solve_dist == 1?"réponse erronée":"réponses erronées"}.
                </ListGroupItem>
            {/if}
            {#if exercice.submitted || sberr}
	        <ListGroupItem class="{messageClass} rounded-0">
                    {#if !sberr}
                        <strong>Votre solution a bien été envoyée !</strong>
                    {:else}
                        <strong>{sberr}</strong> {message}
                    {/if}
                </ListGroupItem>
            {/if}
            {#if timeouted}
	        <ListGroupItem class="text-danger rounded-0">
                    <strong>Oops</strong>
                    La requête a dépassé le délai d'attente. Vous devriez réessayer dans quelques instant&hellip;
                </ListGroupItem>
            {/if}
        </ListGroup>
    {/if}
    {#if !exercice.submitted || sberr}
        <CardBody>
	    <form on:submit|preventDefault={submitFlags}>
                {#each flags as flag ((flag.type?flag.type:"i") + flag.id)}
                    {#if flag.type == "mcq"}
                        <FlagMCQ
                            exercice_id={exercice.id}
                            {flag}
                            {refresh_my}
                            bind:values={responses.mcqs}
                            bind:justifications={responses.justifications}
                        />
                    {:else}
                        <FlagKey
                            exercice_id={exercice.id}
                            {flag}
                            {refresh_my}
                            bind:value={responses.flags[flag.id]}
                        />
                    {/if}
                {/each}

		<div class="form-group mt-2">
		    <Button
                        type="submit"
                        color="danger"
                        disabled={submitInProgress}
                    >
                        {#if submitInProgress}
                            <Spinner size="sm" class="me-2" />
                        {/if}
                        Soumettre
                    </Button>
		</div>
            </form>
        </CardBody>
    {/if}
</Card>
