'use client';

import {Html5Qrcode} from "html5-qrcode";
import {useEffect, useState} from "react";
import LoadingSpinner from "@/components/loading-spinner";
import fetchWithCheck from "@/api-queries/utils/fetch-with-check";

export default function Scanner() {
    const [qrCodeScanner, setQrCodeScanner] = useState<Html5Qrcode | null>(null);
    const [isVerifying, setIsVerifying] = useState<boolean>(false);
    const [result, setResult] = useState<true | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [rescanTimer, setRescanTimer] = useState<number | null>(null);
    const qrCodeSuccessCallback = async (decodedText: string) => {
        stopScanner();
        setIsVerifying(true);

        try {
            const response = await fetchWithCheck<boolean>(`/api/scan`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    code: decodedText
                })
            });

            const newRescanTimer = setTimeout(() => {
                startScanner();
                clearTimeout(newRescanTimer);
            }, 3000);

            setRescanTimer(newRescanTimer as unknown as number);
            setResult(response ? true : null);
        } catch (e: unknown) {
            setError((e as Error).message);
        }

        setIsVerifying(false);
    };
    const qrCodeErrorCallback = (errorMessage: string) => {
        console.log(errorMessage);
    };
    const startScanner = () => {
        if (rescanTimer) {
            setRescanTimer(null);
            clearTimeout(rescanTimer);
        }

        setResult(null);
        setError(null);

        qrCodeScanner?.start(
            {
                facingMode: "environment"
            },
            {
                fps: 1,
                aspectRatio: 1,
                qrbox: (width: number, height: number) => {
                    return {
                        width: 0.7 * width,
                        height: 0.7 * height
                    };
                }
            },
            qrCodeSuccessCallback,
            qrCodeErrorCallback
        );
    };
    const stopScanner = () => {
        qrCodeScanner?.stop();
    };

    useEffect(() => {
        const qrCodeReader = new Html5Qrcode("qr-code-reader");
        setQrCodeScanner(qrCodeReader);

        return () => {
            try {
                qrCodeReader.stop();
                qrCodeReader.clear();
            } catch (e) {
                console.error(e);
            }
        };
    }, []);

    useEffect(() => {
        if (!qrCodeScanner) {
            return;
        }

        startScanner();
    }, [qrCodeScanner]);

    return <div className="flex flex-col gap-5 justify-center items-center pt-20">
        <div id="qr-code-reader" className={`w-[320px] h-[320px] relative ${isVerifying || result || error ? 'hidden' : ''}`}/>

        {isVerifying && <LoadingSpinner/>}

        {result && <div className="flex justify-center items-center w-24 h-24 bg-green-500 rounded-full">
            <svg
                className="w-12 h-12 text-white"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                xmlns="http://www.w3.org/2000/svg"
            >
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
            </svg>
        </div>}

        {error && <div className="flex flex-col gap-5 justify-center items-center">
            <div className="flex justify-center items-center w-24 h-24 bg-red-500 rounded-full">
                <svg
                    className="w-12 h-12 text-white"
                    fill="none"
                    stroke="currentColor"
                    viewBox="0 0 24 24"
                    xmlns="http://www.w3.org/2000/svg"
                >
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12"></path>
                </svg>
            </div>
            <div className="font-bold text-xl">
                {error}
            </div>
        </div>}

        {(result || error) &&
            <button
                onClick={startScanner}
                className={`min-w-[10rem] bg-blue-500 text-white text-lg px-4 py-2 mt-10 rounded ${isVerifying ? 'hidden' : ''}`}
            >
                Scan
            </button>
        }
    </div>;
}
