'use server';
import { AuthError } from "@/fetchers/types/base";
import { scanByRKeyDouble } from "@/fetchers/redis/redisService";
import { getPlainAccessToken } from "./access";
import { nextCrypto } from "@/fetchers/base";
import { getCookieSelectToken, removeCookieTokens, setCookieSelectToken } from "./cookies";

async function getPlainSelectToken() {
    console.log('getPlainSelectToken is triggered...');

    try {
        let encryptedSelectToken = "";

        // Try to get token from cookies first
        const selectCookie = await getCookieSelectToken();
        if (selectCookie?.value) {
            encryptedSelectToken = selectCookie.value;
            console.log('Select token from cookie:', 'found');
        }

        console.log('getPlainSelectToken encryptedSelectToken', encryptedSelectToken ? `${encryptedSelectToken.substring(0, 10)}...` : 'empty');

        if (!encryptedSelectToken) {
            console.log('No select token found');
            throw new AuthError("No select token found");
        }

        const decryptedSelectToken = await nextCrypto.decrypt(encryptedSelectToken) || "";
        console.log('getPlainSelectToken decryptedSelectToken', decryptedSelectToken ? `${decryptedSelectToken.substring(0, 10)}...` : 'empty');

        if (!decryptedSelectToken) {
            console.log('Decrypted select token is invalid or empty');
            throw new AuthError("Select token is invalid");
        }

        return decryptedSelectToken;
    }
    catch (error) {
        console.error('Error in getPlainSelectToken:', error);
        throw new AuthError("No select token found on cookies");
    }
}

async function getSelectToken() {
    try {
        const plainAccessToken = await getPlainAccessToken();
        const plainSelectToken = await getPlainSelectToken();
        console.log('plainAccessToken', plainAccessToken);
        console.log('plainSelectToken', plainSelectToken);
        const scanToken = await scanByRKeyDouble({ rKey: plainAccessToken, sKey: plainSelectToken });
        if (!scanToken) throw new AuthError("Select token is invalid");
        return scanToken;
    }
    catch (error) { throw new AuthError("No select token found in headers") }
}

async function setSelectToken(token: string) {
    console.log('setSelectToken is triggered...');
    await setCookieSelectToken(token);
}

async function isSelectTokenValid() {
    try {
        const selectToken = await getSelectToken();
        console.log('isSelectTokenValid selectToken', selectToken);
        if (selectToken) return true;
    } catch (error) {
        console.log('isSelectTokenValid error', error);
        return false
    }
}

async function removeSelectToken() {
    console.log('removeSelectToken is triggered');
    await removeCookieTokens();
}

export { getSelectToken, setSelectToken, removeSelectToken, getPlainSelectToken, isSelectTokenValid };
