import { useEffect } from "react";
import { useProtocolState } from "../ProtocolProvider/useProtocolState";
import { ProtocolState } from "../ProtocolProvider/ProtocolProvider";
import { useDatabase } from "../DatabaseProvider/useDatabase";
import { usePublicKey } from "../AccountProvider/usePublicKey";
import { PacketSync, SyncStatus } from "../ProtocolProvider/protocol/packets/packet.sync";
import { useSender } from "../ProtocolProvider/useSender";
import { usePacket } from "../ProtocolProvider/usePacket";
import { whenFinish } from "./dialogQueue";
import { useProtocol } from "../ProtocolProvider/useProtocol";

/**
 * Хук отвечает за синхронизацию сообщений, запрос синхронизации
 * при подключении
 */
export function useSynchronize() {
    const [_, setProtocolState] = useProtocolState();
    const {getQuery, runQuery} = useDatabase();
    const publicKey = usePublicKey();
    const send = useSender();
    const {protocol} = useProtocol();

    useEffect(() => {
        if(protocol.handshakeExchangeComplete){
            trySync();
        }
    }, [protocol.handshakeExchangeComplete]);

    const trySync = async () => {
        const lastSyncTime = await getQuery(`SELECT last_sync FROM accounts_sync_times WHERE account = ?`, [publicKey]);
        sendSynchronize(lastSyncTime?.last_sync ?? 0);
    }

    const sendSynchronize = (timestamp: number) => {
        const packet = new PacketSync();
        packet.setStatus(0);
        packet.setTimestamp(timestamp);
        send(packet);
    }

    usePacket(25, async (packet: PacketSync) => {
        const status = packet.getStatus();
        if(status == SyncStatus.BATCH_START){
            setProtocolState(ProtocolState.SYNCHRONIZATION);
        }
        if(status == SyncStatus.BATCH_END){
            console.info("Batch start");
            await whenFinish();
            console.info("Batch finished");
            await runQuery(
                "INSERT INTO accounts_sync_times (account, last_sync) VALUES (?, ?) " +
                "ON CONFLICT(account) DO UPDATE SET last_sync = ? WHERE account = ?",
                [publicKey, packet.getTimestamp(), packet.getTimestamp(), publicKey]
            );               
            console.info("Batch complete", publicKey, packet.getTimestamp());  
            trySync();    
        }
        if(status == SyncStatus.NOT_NEEDED){
            /**
             * Синхронизация не нужна, все данные актуальны
             */
            setProtocolState(ProtocolState.CONNECTED);
        }
    }, [publicKey]);
}