class PaylayClient {
    url = PRODUCTION_MODE
        ? "not supported"
        : "http://127.0.0.1:5001/prime-micron-374215/us-central1/paylay"

    // -------------- COLLECTION NAMES ------------------
    connectionCollectionName = "database_connections"
    customerCollectionName = "customers"
    propertiesCollectionName = "properties"
    // --------------------------------------------------

    async callPaylay(data) {
        try {
            const resp = await fetch(this.url,
                {
                    method: "POST",
                    mode: "cors",
                    headers: {
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify(data), // body data type must match "Content-Type" header
                })
            return await resp.json()
        } catch (e) {
            // TODO: handle errors
            throw e
        }

    }

    oracleConnection(username, password, url) {
        return {
            username,
            password,
            url,
            type: "oracle"
        }
    }
    /**
     * Saves a connection details to firestore
     */
    async saveConnection(connection_name, connection_details) {
        await this.setProperty({ id: connection_name, value: connection_details })
    }
    /**
     * gets the connection from firestore
     * @param {string} connection_name the name of the connection
     * @returns 
     */
    async getConnection(connection_name) {
        return await this.getProperty(connection_name)
    }
    /**
     * sets property params for a user. 
     * Will throw if property values are to large to store in a firestore feild.
     * @param {{id: string, value: any}} property_params 
     */
    async setProperty(property_params) {
        const { setDoc, db, doc } = firebase.firestore
        const user = await getUser()
        if (user) {
            try {
                const doc_ref = doc(db, this.customerCollectionName, user.uid, this.propertiesCollectionName, property_params.id)
                await setDoc(doc_ref, { value: this.firestoreStringify(property_params.value) })
            } catch (e) {
                throw e // TODO: error handling
            }
        }
    }
    /**
     * sets array of properties
     * Will throw if property values are to large to store in a firestore feild.
     * @param {[{id: string, value: any}]} properties 
     */
    async setProperties(properties) {
        const proms = []
        for (const property of properties) {
            proms.push(this.setProperty(property))
        }
        await Promise.all(proms)
    }
    /**
    * gets property for a user
    * @param {string} id 
    */
    async getProperty(id) {
        const { getDoc, db, doc } = firebase.firestore
        const user = await getUser()
        if (user) {
            try {
                const doc_ref = doc(db, this.customerCollectionName, user.uid, this.propertiesCollectionName, id)
                const docSnap = await getDoc(doc_ref);
                if (docSnap.exists()) {
                    return JSON.parse(docSnap.data().value)
                } else {
                    return undefined
                }
            } catch (e) {
                return undefined
            }
        }
    }

    /**
     * Converts given data to JSON string. Then checks if the byte size is small enough for firestore to handle.
     * Throws `DataToLargeForFirestore` when byte size is to large
     * @param data 
     * @returns string
     */
    firestoreStringify(data) {
        const str = JSON.stringify(data)
        const size = byteSize(str)
        if (size > 1_048_487) {
            throw new DataToLargeForFirestore(size)
        }
        return str
    }

    // used for convienacne. Since PaylayClient does not manage state this is very safe to use.
    // if PaylayClient does end up managing state, only use this for simple calls / times 
    // when you want to deal with universal state.  
    static shared = new PaylayClient()
}