import { Show, createMemo, createSignal } from "solid-js";
import { FilledButton } from "../components/FilledButton";
import { FilledCard } from "../components/FilledCard";
import { LoadingIcon } from "../icons/LoadingIcon";
import { MagnifyingGlassIcon } from "../icons/MagnifyingGlassIcon";
import { LoadingStatus, useLoading } from "../utils/functions";
import { ScansList } from "./ScansList";

/**
 * Represents the data about the scans that were detected.
 * Serialization & Deserialization is done by the backend.
 */
export interface ScanData {
    Ok: Array<ScanResult>,
}

export type ScanResult =
    | { Full: [string, number, string] }
    | { Partial: [string, string] }
    | { Empty: string }
    | { Error: string };



export function Scans() {
    const { status, setStatus, error, setError } = useLoading();
    const [scanData, setScanData] = createSignal<Array<ScanResult> | null>(null);
    const [converted, setConverted] = createSignal(false);

    const loading = createMemo(() => status() === LoadingStatus.Loading);

    const detectScans = () => {
        setStatus(LoadingStatus.Loading);
        setScanData(null);
        setConverted(false);

        fetch(`${import.meta.env.VITE_BACKEND_URL}/api/scans/detect`)
            .then((res) => res.json())
            .then((data) => {
                setStatus(LoadingStatus.Ok);
                setScanData(data.Ok);
            })
            .catch((err) => {
                setStatus(LoadingStatus.Error);
                console.error(err);
                setError(err.Error);
            });
    };


    return (
        <div class="grid grid-cols-[25rem_25rem_auto]">
            <div>
                <FilledCard>
                    <h1 class="py-2 px-4 font-medium text-xl mb-2">
                        Escaneos
                    </h1>
                    <div class="px-4 pb-4">
                        Esta sección del sistema realiza lo siguiente:
                        <br />
                        (1) Detecta el código QR en los escaneos
                        <br />
                        (2) Rota el escaneo a posición horizontal
                        <br />
                        (3) Convierte los escaneos a PDF
                        <br />
                        (4) Coloca el nombre correcto al PDF según el formato:
                        <br />
                        <code class="border border-c-outline rounded p-1 bg-c-background">
                            &lt;NOMBRES&gt; &lt;APELLIDOS&gt; - &lt;CURSO&gt;.pdf
                        </code>
                        <hr class="my-2" />
                        Si el sistema no detecta el código QR, se debe realizar el
                        paso (4) manualmente.
                    </div>
                </FilledCard>

                <FilledCard>
                    <h1 class="py-2 px-4 font-medium text-xl mb-2">
                        Parámetros de detección
                    </h1>
                    <div class="px-4 pb-4">
                        Para que el sistema detecte y clasifique automáticamente los escaneos
                        se debe cumplir lo siguiente:
                        <ol class="py-2 px-2 list-decimal list-inside">
                            <li>
                                Escanear el certificado en formato&nbsp;
                                <code class="border border-c-outline rounded p-1 bg-c-background">
                                    jpg
                                </code>
                            </li>
                            <li>
                                El nombre del archivo debe iniciar con&nbsp;
                                <code class="border border-c-outline rounded p-1 bg-c-background">
                                    eeg
                                </code>
                            </li>
                            <li>
                                El nombre del archivo debe terminar en&nbsp;
                                <code class="border border-c-outline rounded p-1 bg-c-background">
                                    .jpg
                                </code>
                            </li>
                            <li>
                                El nombre del archivo puede tener otras letras en medio,
                                siempre que se cumplan las condiciones anteriores.
                            </li>
                        </ol>
                        Por ejemplo, los siguientes nombres de archivo son válidos:
                        <ul class="py-2 px-2 list-disc list-inside">
                            <li>
                                <code class="border border-c-outline rounded p-1 bg-c-background">
                                    eeg.jpg
                                </code>
                            </li>
                            <li>
                                <code class="border border-c-outline rounded p-1 bg-c-background">
                                    eeg0001.jpg
                                </code>
                            </li>
                            <li>
                                <code class="border border-c-outline rounded p-1 bg-c-background">
                                    eeg archivo con letras en medio.jpg
                                </code>
                            </li>
                        </ul>
                    </div>
                </FilledCard>

            </div>
            <div>
                <FilledCard>
                    <h1 class="py-2 px-4 font-medium text-xl mb-2">
                        Detectar escaneos
                    </h1>
                    <div class="px-4 pb-4">
                        <p>
                            El siguiente botón detectará los archivos
                            que cumplen con los parámetros de detección
                            en la carpeta <code>ESCANEOS</code>, y mostrará los resultados abajo.
                        </p>


                        <div class="relative">
                            <FilledButton
                                onClick={detectScans}
                                disabled={loading()}
                            >
                                <span
                                    class="absolute top-[1.35rem] left-2"
                                    style={{ display: loading() ? "none" : "inline-block" }}
                                >
                                    <MagnifyingGlassIcon
                                        fill="var(--c-on-primary)"
                                    />
                                </span>
                                <span
                                    class="absolute top-[1.35rem] left-2"
                                    style={{ display: loading() ? "inline-block" : "none" }}
                                >
                                    <LoadingIcon
                                        class="animate-spin"
                                        fill="var(--c-primary-container)"
                                    />
                                </span>

                                <span class="ml-5">
                                    Detectar escaneos
                                </span>
                            </FilledButton>
                        </div>

                        <Show when={status() === LoadingStatus.Error}>
                            <p>
                                Error detectando escaneos: {error()}
                            </p>
                        </Show>
                    </div>
                </FilledCard>

                <ScansList scanData={scanData()} onSuccess={() => {
                    setConverted(true);
                    setScanData(null);
                }}
                />

                <Show when={converted()}>
                    <FilledCard>
                        <h1 class="py-2 px-4 font-medium text-xl mb-2">
                            Archivos convertidos con éxito
                        </h1>
                    </FilledCard>
                </Show>
            </div>
        </div>
    );
}
