
/**
 * Camera Component would save the photo with location
 */

import React, { useState, useEffect, useContext } from "react";

import { Typography, Button, message } from 'antd';

import { ScanOutlined, LoadingOutlined, SecurityScanOutlined } from '@ant-design/icons';

import './finger-print-search.scss';

const { Title } = Typography;

export default function FingerPrintSearch({ value, onScan, onSearch }) {

    // Response
    const [response, setResponse] = useState(value);

    const [loading, setLoading] = useState(false);

    /**
     * Function that starts / restarts scanning
     */
    async function startScanning() {

        setLoading(true);

        const result = await readFingerPrint()

        // Fetch the data with the fingerprint has to be compared with 
        const candidates = await onScan();

        console.log(candidates);

        // For each of the candidates , search to find the first matching one
        // Find the candidates asynchronously
        await findAsync(candidates, async ({ candidate }) => {

            // Fingerprint
            if (candidate.fingerprint && result.TemplateBase64) {

                // Compare the template
                const { score } = await compareTemplate(result.TemplateBase64, candidate.fingerprint);

                // 
                if (score) {

                    return {
                        ...candidate,
                        scan: true,
                        score
                    }

                } else {


                    return {
                        ...candidate,
                        scan: false,
                    }

                }


            } else {

                // 
                return {
                    ...candidate,
                    scan: false,
                    score: null
                }
            }
        })

        setLoading(false);
    }

    /**
     * Execute the function with the callback passed
     * 
     * @param {*} arr 
     * @param {*} asyncCallback 
     * @returns 
     */
    async function findAsync(arr, asyncCallback) {

        const promises = arr.map(asyncCallback);

        const results = await Promise.all(promises);

        const index = results.findIndex(result => {

            return result.scan;

        });

        // On Search
        onSearch(arr[index]);

        // On Search
        return arr[index];
    }

    /**
     * Read the fingerprint
     */
    async function readFingerPrint() {

        let formBody = {
            Timeout: 10000,
            Quality: "50",
            // "Licstr": "123hE/78I5oOUJnm5fa5zDDRrEJb5tdqU71AVe+/Jc2RK0=",
            "templateFormat=": "ISO",
            "imageWSQRate=": "0.75",
        };

        // return ApiUtils.post({ url: "https://localhost:8443/SGIFPCapture", formBody })
        return fetch("https://localhost:8000/SGIFPCapture", {
            headers: {
                // 'Content-Type': 'application/json',
            },
            method: 'POST',
            body: formBody
        })
            .then((res) => res.json())
            .then((json) => {

                console.log(json);

                setResponse(json);

                // #Note Disabling upload here so that we save unwanted file uplaods
                // The file needs to be manually uploaded to the sytem 
                // onChange(`data:image/png;base64,${json.BMPBase64}`);

                // onChange(`${json.TemplateBase64}`)
                return json;

            });
    }


    /**
     * Compare the template
    * 
    * @param {*} template1 
    * @param {*} template2 
    * @returns 
    */
    function compareTemplate(template1, template2) {

        let payload = "template1=" + encodeURIComponent(template1) + '&template2=' + encodeURIComponent(template2) + '&templateFormat=ISO';

        return fetch("https://localhost:8000/SGIMatchScore", {
            method: 'POST',
            body: payload,
        })
            .then((res) => res.json())
            .then((json) => {

                if (json.MatchingScore > 100) {

                    return {
                        score: json.MatchingScore,
                        succes: true
                    }

                } else {

                    return {
                        success: false
                    }

                }
            });
    }

    return (<div className="finger-print-search">

        <Button size={'small'} type={!loading ? 'primary' : 'secondary'} onClick={() => { startScanning(true); }}>

            <SecurityScanOutlined />

            {
                loading
                    ?
                    <>

                        <LoadingOutlined /> Loading
                    </>
                    :
                    'Read'
            }
        </Button>

    </div>)
}
