import { useConsoleLogger } from "@/app/hooks/useConsoleLogger";
import { useDatabase } from "@/app/providers/DatabaseProvider/useDatabase";
import { createContext, useEffect, useState } from "react";

export interface AccountBase {
    publicKey: string;
    privateKey: string;
    seedPhraseEncrypted: string;
}

export interface Account extends AccountBase {
    privatePlain: string;
    privateHash: string;
}

export interface AccountContextValue {
    allAccounts: AccountBase[];
    loginedAccount: Account;
    loginAccount: (account : Account) => void;
    createAccount: (account : Account) => void;
    loginDiceAccount: AccountBase;
    accountProviderLoaded: boolean;
    removeAccountFromLoginDice: () => void;
    removeAccountsFromArrayOfAccounts: (accountBase : AccountBase) => void;
    selectAccountToLoginDice: (accountBase : AccountBase) => void;
    setAccounts: (accounts: AccountBase[]) => void;
}

export const AccountContext = createContext<any>({});

interface AccountProviderProps {
    children: React.ReactNode;
}

export function AccountProvder(props : AccountProviderProps){
    const {allQuery, runQuery} = useDatabase();
    const [accounts, setAccounts] = useState<AccountBase[]>([]);
    const [loginDice, setLoginDice] = useState<AccountBase>({
        publicKey: "",
        privateKey: "",
        seedPhraseEncrypted: ""
    });
    const [account, setAccount] = useState<Account>({
        publicKey: "",
        privatePlain: "",
        privateKey: "",
        privateHash: "",
        seedPhraseEncrypted: ""        
    });
    const [loaded, setLoaded] = useState(false);
    const {info} = useConsoleLogger("AccountProvider");
    
    useEffect(() => {
        loadAllAccountFromDb();
    }, []);

    useEffect(() => {
        if(!loaded){
            return;
        }
        loadLastLoginDice();
    }, [accounts, loaded]);

    const loadLastLoginDice = () => {
        let publicKey = localStorage.getItem("last_logined_account");
        if(!publicKey && accounts.length <= 0){
            return;
        }
        if(!publicKey && accounts.length > 0){
            setLoginDice(accounts[0]);
            return;
        }
        for(let i = 0; i < accounts.length; i++){
            let accountBase = accounts[i];
            if(accountBase.publicKey == publicKey){
                setLoginDice(accountBase);
                return;
            }
        }
        /**
         * Если last_logined_account плохой - то убираем этот аккаунт
         */
        removeAccountFromLoginDice();
    }

    const removeAccountsFromArrayOfAccounts = (accountBase : AccountBase) => {
        setAccounts((prev) => prev.filter((v) => v.publicKey !== accountBase.publicKey));
    }

    const loadAllAccountFromDb = async () => {
        const result = await allQuery("SELECT * FROM `accounts`");
        let resultSet : AccountBase[] = [];
        for(let i = 0; i < result.length; i++){
            let acc = result[i];
            resultSet.push({
                publicKey: acc.public_key,
                privateKey: acc.private_key,
                seedPhraseEncrypted: acc.sfen
            });
        }
        setAccounts(resultSet);
        setLoaded(true);
    }

    const loginAccount = (account : Account) => {
        info("Logging in account with public key: " + account.publicKey);
        setAccount(account);
    }

    const createAccount = (account : Account) => {
        runQuery("INSERT INTO accounts (public_key, private_key, sfen) VALUES (?, ?, ?)", [account.publicKey, account.privateKey, account.seedPhraseEncrypted]);
        //maybe set state accounts
    }

    const selectAccountToLoginDice = (accountBase: AccountBase) => {
        setLoginDice(accountBase);
        localStorage.setItem("last_logined_account", accountBase.publicKey);
    }

    const removeAccountFromLoginDice = () => {
        setLoginDice({
            publicKey: "",
            privateKey: "",
            seedPhraseEncrypted: ""
        });
        localStorage.removeItem("last_logined_account");
    }

    return (
        <AccountContext.Provider value={{
            allAccounts: accounts,
            loginedAccount: account,
            loginAccount: loginAccount,
            createAccount: createAccount,
            loginDiceAccount: loginDice,
            accountProviderLoaded: loaded,
            removeAccountsFromArrayOfAccounts: removeAccountsFromArrayOfAccounts,
            removeAccountFromLoginDice: removeAccountFromLoginDice,
            selectAccountToLoginDice: selectAccountToLoginDice,
            setAccounts
        }}>
            {loaded && (props.children)}
        </AccountContext.Provider>
    )
}