<script>
 import { createEventDispatcher } from 'svelte';

 import DateFormat from '../components/DateFormat.svelte';
 import { WorkRepository, getRemoteRepositories, getRepositories } from '../lib/repositories';
 import { ToastsStore } from '../stores/toasts';

 const dispatch = createEventDispatcher();

 let className = '';
 export { className as class };

 export let work = {};
 export let readonly = false;

 let repo_work = null;
 let repo_used = null;
 let remote_repos = [];
 let repo_pull_state = null;
 let show_logs = null;

 function updatePullState(repo) {
     repo_pull_state = repo.getBuildState();
     show_logs = null;
     repo_pull_state.then((state) => {
         if (state.status == "pending" || state.status == "running") {
             setTimeout(() => updatePullState(repo), state.status == "pending" ? 1000 : 3000);
         } else if (state.status == "success") {
             dispatch('update_submission');
         }
     })
 }

 function showLogs(repo) {
     show_logs = repo.getBuildLogs()
 }

 function refresh_repo_work() {
     repo_work = getRepositories(work.id);
     repo_work.then((repos) => {
         repo_used = repos[0];
         updatePullState(repos[0])
     }, () => {
         repo_used = new WorkRepository({id_work: work.id});
         remote_repos = getRemoteRepositories();
     });
 }
 refresh_repo_work();

 let submitInProgress = false;
 function submitWorkRepository() {
     submitInProgress = true;
     repo_used.save().then(() => {
	 submitInProgress = false;
         refresh_repo_work();
     }, (error) => {
	 submitInProgress = false;
         ToastsStore.addErrorToast({
             msg: "Une erreur s'est produite durant la création de la liaison au dépôt : " + error,
         });
     });
 }

 function goRetrieveWork(repo) {
     submitInProgress = true;
     repo.retrieveWork().then(() => {
	 submitInProgress = false;
         refresh_repo_work();
     }, (error) => {
	 submitInProgress = false;
         ToastsStore.addErrorToast({msg: "Une erreur s'est produite : " + error});
     })
 }
</script>

{#await repo_work}
    <div class="{className} text-center">
        <div class="spinner-border text-primary mx-3" role="status"></div>
        <span>Chargement de vos préférences de rendu &hellip;</span>
    </div>
{:then repos}
    {#each repos as repo (repo.id)}
        <div class="{className} card">
            <div class="card-body d-flex justify-content-between">
                <div class="d-flex flex-column justify-content-center">
                    <div>
                        <div class="row">
                            <label for={repo.id + "url"} class="col-sm-6 col-form-label">Dépôt lié&nbsp;:</label>
                            <div class="col-sm-6">
                                <input type="text" class="form-control form-control-sm" style="font-family: monospace" disabled id={repo.id + "url"} value={repo.uri}>
                            </div>
                        </div>
                        <div class="row">
                            <label for={repo.id + "secret"} class="col-sm-6 col-form-label">Webhook Secret token (à indiquer dans GitLab)&nbsp;:</label>
                            <div class="col-sm-6">
                                <div class="input-group">
                                    <input type={repo.show_secret?"text":"password"} class="form-control form-control-sm" disabled id={repo.id + "secret"} value={repo.secret}>
                                    <button class="btn btn-sm btn-outline-info" on:click={() => { repo.show_secret = !repo.show_secret}}>
                                        <i class="bi" class:bi-eye={!repo.show_secret} class:bi-eye-slash={repo.show_secret}></i>
                                    </button>
                                </div>
                            </div>
                        </div>
                        Dernière récupération&nbsp;: <strong>{#if repo.last_check}<DateFormat date={new Date(repo.last_check)} dateStyle="medium" timeStyle="medium" />{:else}-{/if}</strong>
                        {#if repo_pull_state}
                            {#await repo_pull_state}
                                <div class="spinner-grow spinner-grow-sm mx-1" role="status"></div>
                            {:then state}
                                {#if state.status == "pending" || state.status == "running"}
                                    <div
                                        class="spinner-grow spinner-grow-sm mx-1"
                                        class:text-primary={state.status == "pending"}
                                        class:text-warning={state.status == "running"}
                                        title="La récupération est en cours"
                                        role="status"
                                    ></div>
                                {:else if state.status == "success"}
                                    <i class="bi bi-check-circle-fill text-success mx-1" title="La récupération s'est bien passée"></i>
                                {:else if state.status == "failure"}
                                    <i class="bi bi-exclamation-circle-fill text-danger mx-1" title="La récupération ne s'est pas bien passée" style="cursor: pointer" on:click={() => showLogs(repo)}></i>
                                {:else}
                                    {state.status}
                                {/if}
                            {/await}
                        {/if}
                    </div>
                </div>
                <div class="d-flex flex-column justify-content-center">
                    <button
                        type="button"
                        class="btn btn-outline-info float-end mb-1"
                        disable={submitInProgress || readonly}
                        on:click={() => goRetrieveWork(repo)}
                    >
                        Récupérer mon travail
                    </button>
                    <button
                        type="button"
                        class="btn btn-outline-danger float-end mt-1"
                        disable={submitInProgress || readonly}
                        on:click={() => repo.delete().then(() => { refresh_repo_work() }, (error) => ToastsStore.addErrorToast({msg: "Une erreur s'est produite durant la suppression du lien : " + error}))}
                    >
                        Supprimer cette liaison
                    </button>
                </div>
            </div>
            {#if show_logs}
                {#await show_logs then logs}
                    <div class="card-body d-flex justify-content-between bg-dark text-light">
                        <pre class="pb-2">{#each logs as l (l.pos)}{l.out}{/each}</pre>
                    </div>
                {/await}
            {/if}
        </div>
    {/each}
{:catch}
    {#if !readonly}
        <p>
            Voici la liste des dépôts reconnus&nbsp;:
        </p>
        <form class="{className} form-floating" on:submit|preventDefault={submitWorkRepository}>
            {#await remote_repos}
                <div class="text-center">
                    <div class="spinner-border text-primary mx-3" role="status"></div>
                    <span>Récupération de vos dépôts GitLab &hellip;</span>
                </div>
            {:then rrepos}
                <select class="form-select col" disabled={readonly} bind:value={repo_used.uri}>
                    {#each rrepos as r (r.Id)}
                        <option value={r.ssh_url_to_repo}>{r.path_with_namespace}</option>
                    {/each}
                </select>
                <label>Dépôt GitLab pour ce travail&nbsp;:</label>
            {/await}
            <button
                type="submit"
                class="mt-2 btn btn-primary"
                disable={submitInProgress || readonly}
            >
                Utiliser ce dépôt
            </button>
            <button
                type="button"
                class="mt-2 btn btn-info"
                title="Rafraîchir la liste des dépôts"
                on:click={() => remote_repos = getRemoteRepositories()}
            >
                <i class="bi bi-arrow-clockwise"></i>
            </button>
        </form>
    {/if}
{/await}
