// @type="module"@ This tells the blog engine to use the module tag when we are in module mode, we can be free with the functions
// we declare! (there will be no collisions)

// It is safe to do thus because we are in module mode. If we are not in module mode, then it is 
// safer to call the methods directly from the window object
const {
    getAuth,
    onAuthStateChanged,
    createUserWithEmailAndPassword,
    signInWithEmailAndPassword,
    signOut,
} = firebase.auth
const { getFunctions, httpsCallableFromURL } = firebase.functions

const auth = getAuth();

const root_node = document.getElementById("user-profile-asd")
const loading = ui_div("loading", "")
const error_message = ui_div("error-message")


function profile(user) {
    return ui_div("center",
        ui_div("user-info",
            ui_div("user-icon", user.email[0].toUpperCase()),
            ui_div("user-email", user.email),
            signOutUI(auth),
        ),
    )
}

function signInUI() {
    return ui_div("center", ui_sign_in_form())
}

function signUpUI() {
    return ui_div("center", ui_sign_up_form())
}

function signOutUI(firebaseAuth) {
    const signOutBtn = ui_btn_error("Sign Out")
    signOutBtn.onclick = async () => await signOut(firebaseAuth)
    return signOutBtn
}

async function getStripePortalLink() {
    if (cache.stripeLink) {
        return cache.stripeLink
    }
    const functions = getFunctions()
    const createPortalLink = httpsCallableFromURL(
        functions,
        "https://us-west3-prime-micron-374215.cloudfunctions.net/ext-firestore-stripe-payments-createPortalLink"
    );
    const { data } = await createPortalLink({
        returnUrl: window.location.origin,
    })
    cache.stripeLink = data.url
    return data.url
}


async function productAndPriceData() {
    const products = []
    const querySnapshot = await getDocs(collection(db, "products"));
    querySnapshot.forEach(async (productDoc) => {
        const product_data = productDoc.data()
        if (product_data.active) {
            products.push({
                docID: productDoc.id,
                ...product_data
            })
        }
    })
    const prices_snapshot_promise = []
    for (const product of products) {
        prices_snapshot_promise.push(getDocs(collection(db, "products", product.docID, "prices")))
    }
    const product_and_price = []
    const snapshots = await Promise.all(prices_snapshot_promise)
    for (const priceSnapshot of snapshots) {
        priceSnapshot.forEach(priceDoc => {
            const price = priceDoc.data()
            product_and_price.push({
                product: products.find(x => x.docID === price.product),
                price: price,
                productID: price.product,
                priceID: priceDoc.id,
            })
        })
    }
    return product_and_price
}

// console.log(product_data)
// const prices = []
// const pricesSnapshot = await getDocs(collection(db, "products", productDoc.id, "prices"))
// console.log("sb", pricesSnapshot)
// pricesSnapshot.forEach((priceDoc) => {
//     const price = priceDoc.data()
//     console.log(price)

//     if (price.active) {
//         prices.push({
//             dollar_amount: priceData.unit_amount / 100,
//             type: price.type,
//         })
//     }
// })

// products.push({
//     product: product_data,
//     prices: prices
// })

async function get_product_data() {
    const purchasedProducts = await getPurchasedProducts()
    const querySnapshot = await getDocs(collection(db, "products"));
    // const stripeLink = await getStripePortalLink()
    const grid = ui_grid()
    querySnapshot.forEach(async (productDoc) => {
        const product_data = productDoc.data()
        const product_features = Object.entries(product_data.metadata)
            .filter((([key]) => key.match(/feature_\d+/)))
            .sort((a, b) => a[0] > b[0])
            .map(([_, value]) => ui_first_letter_upper_case(value))
        if (product_data.active) {
            const pricesSnapshot = await getDocs(collection(db, "products", productDoc.id, "prices"))
            pricesSnapshot.forEach((priceDoc) => {
                const priceData = priceDoc.data()
                if (priceData.active) {
                    const dollar_amount = priceData.unit_amount / 100

                    let price
                    if (priceData.type === "one_time") {
                        price = ui_div("center price-tag", "$", dollar_amount)
                    } else {
                        // its a subscription so we need to show the interval
                        price = ui_div("center price-tag", "$", dollar_amount, " / ", priceData.interval)
                    }

                    const description = ui_card_body_item("", price, ui_br())
                    const features = ui_div("", ui_ul("card-ul-padding", ...product_features.map(x => ui_li("", x))))

                    const purchasedProduct = purchasedProducts.find(x => x.productId === productDoc.id)
                    if (purchasedProduct) {
                        console.log(purchasedProduct);
                        grid.append(ui_grid_item(managePurchaseCard(product_data, description, features, stripeLink)))
                    } else {
                        const buy_btn = ui_btn("Buy Now")
                        buy_btn.onclick = async () => {
                            buy_btn.disabled = true
                            buy_btn.innerText = "Heading to checkout..."
                            try {
                                await checkout_product(priceDoc.id, priceData.type)
                            } catch (error) {
                                if (error === "user abort") {
                                    // the user simply quit. So we dont have to do anything.
                                } else {
                                    console.error(error)
                                }
                            } finally {
                                buy_btn.innerText = "Buy Now"
                                buy_btn.disabled = false
                            }
                        }

                        const head = ui_card_head(product_data.name, ui_first_letter_upper_case(product_data.description))
                        const card = ui_card(head, description, buy_btn, features)
                        grid.append(ui_grid_item(card))
                    }

                }
            })
        }
    });
    tag("available-products").replaceChildren(grid)
}

function managePurchaseCard(product_data, description, features, stripeLink) {
    const buy_btn = ui_btn_info("Loading")
    buy_btn.replaceChildren("Manage")
    buy_btn.onclick = () => window.location.assign(stripeLink)
    const head = ui_card_head(product_data.name, ui_first_letter_upper_case(product_data.description))
    const card = ui_card(head, description, buy_btn, features)
    return card
}

/**
 * gets the users purchased products. If the user did not buy anything, or
 * the user is not signed in, then this method will return null. 
 * @returns
 */
async function getPurchasedProducts(user) {
    if (!user) { return [] }
    const usersSubsSnapshot = await getDocs(collection(db, "customers", user.uid, "subscriptions"))
    const subs = []
    usersSubsSnapshot.forEach(x => x = subs.push(x.data()))
    return subs.map(x => ({ ...x, productID: x.items[0].plan.product }))
}

async function checkout_product(price_id, price_type) {
    await new Promise((resolve, reject) => {
        const overlay = ui_div("overlay")
        onAuthStateChanged(auth, async (user) => {
            if (!user) {
                overlay.id = "overlay"

                const modal_x = ui_span("material-symbols-outlined button inline-icon", "close")
                modal_x.onclick = () => {
                    overlay.remove()
                    reject("user abort")
                }
                const modal_title = ui_div("modal-title right", "", modal_x)

                const modal_content = ui_div("modal-content p3 auth-container-in-modal",
                    ui_auth_form()
                )

                const modal = ui_div("modal", modal_title, modal_content)
                const modal_page = ui_div("modal-page", modal)

                overlay.append(modal_page)
                document.body.append(overlay)
            } else {
                overlay.remove()
                const checkoutPayload = {
                    price: price_id,
                    success_url: window.location.origin,
                    cancel_url: window.location.origin,
                }
                if (price_type === "one_time") { checkoutPayload.mode = "payment" }

                const checkout_session_ref = collection(db, "customers", user.uid, "checkout_sessions");
                const ref = await addDoc(checkout_session_ref, checkoutPayload)
                onSnapshot(ref, (snap) => {
                    const { error, url } = snap.data();
                    if (error) {
                        alert(`An error occured: ${error.message}`);
                        reject(`An error occured: ${error.message}`)
                    }
                    if (url) {
                        // We have a Stripe Checkout URL, let's redirect.
                        resolve()
                        window.location.assign(url);
                    }
                });
            }
        })
    })

}


// run this function only when the file is built/loaded in the client.
(async () => {
    root_node.append(loading)
    const product_and_price = await productAndPriceData()
    console.log(product_and_price)
    await new Promise(() => {
        onAuthStateChanged(auth, async (user) => {
            root_node.replaceChildren()
            let p_a_p = product_and_price
            if (user) {
                const purchased_products = await getPurchasedProducts(user)
                p_a_p = markProductsAsPurchased(p_a_p, purchased_products)
                root_node.append(profile(user))
            } else {
                root_node.append(ui_auth_form())
            }

            root_node.append(uiProductsWithPrices(p_a_p))
        })
    })


})()



function markProductsAsPurchased(products_and_prices, purchased_products) {
    return products_and_prices.map(product_and_price => {
        console.log(purchased_products)
        const purchased_product = purchased_products.find(purchased_product => purchased_product.productID === product_and_price.productID)
        console.log(purchased_product)
        if (purchased_product) {
            return { ...product_and_price, purchased: true,  }
        }
        return product_and_price
    })
}

function uiProductsWithPrices(product_and_price) {
    console.log(product_and_price)
    const grid = ui_grid()
    for (const { product, price, priceID, purchased } of product_and_price) {
        const dollar_amount = price.unit_amount / 100
        const product_features = Object.entries(product.metadata)
            .filter((([key]) => key.match(/feature_\d+/)))
            .sort((a, b) => a[0] > b[0])
            .map(([_, value]) => ui_first_letter_upper_case(value))

        let price_div
        if (price.type === "one_time") {
            price_div = ui_div("center price-tag", "$", dollar_amount)
        } else {
            price_div = ui_div("center price-tag", "$", dollar_amount, " / ", price.interval)
        }

        const description = ui_card_body_item("", price_div, ui_br())
        const features = ui_div("", ui_ul("card-ul-padding", ...product_features.map(x => ui_li("", x))))

        if (purchased) {
            grid.append(ui_grid_item(managePurchaseCard(product, description, features, "stripeLink")))
        } else {

            const buy_btn = ui_btn("Buy Now")
            buy_btn.onclick = async () => {
                buy_btn.disabled = true
                buy_btn.innerText = "Heading to checkout..."
                try {
                    await checkout_product(priceID, price.type)
                } catch (error) {
                    if (error === "user abort") {
                        // the user simply quit. So we dont have to do anything.
                    } else {
                        console.error(error)
                    }
                } finally {
                    buy_btn.innerText = "Buy Now"
                    buy_btn.disabled = false
                }
            }

            const head = ui_card_head(product.name, ui_first_letter_upper_case(product.description))
            const card = ui_card(head, description, buy_btn, features)
            grid.append(ui_grid_item(card))
        }
    }
    return grid
}




// testing can delete
// testing
//  const echo_btn = ui_btn("send request")
//  echo_btn.onclick = async () => {
//      const client = new PaylayClient()
//      const payload = await client.getProperty("sql_book_connection")
//      console.log(payload)
//      const data = {
//          mode: "check-oracle-connection",
//          payload: { sql: "select * from canvas.work", ...payload },
//      }
//      console.log(await client.callPaylay(data))
//  }

//  const saveConnection = ui_btn("save conection")
//  saveConnection.onclick = async () => {
//      const client = new PaylayClient()
//      console.log("before")
//      const data = await client.saveConnection("sql_book_connection", client.oracleConnection(
//          "BOOK_USER",
//          "Delphi.12345",
//          "https://g4a14350af40031-s5yqhywqp1d9jghc.adb.us-phoenix-1.oraclecloudapps.com/ords/book_user/_/sql"))
//      console.log("--->", data)

//  }
//  const getConnection = ui_btn("get conection")
//  getConnection.onclick = async () => {
//      const client = new PaylayClient()
//      console.log("before")
//      const data = await client.getConnection("sql_book_connection")
//      console.log("--->", data)

//  }
//  const callServerPost = ui_btn("server post")
//  callServerPost.onclick = async () => {

//  }
//  const signout = ui_btn_error("sign out")
//  signout.onclick = async () => {
//      firebase.auth.signOut(firebase.auth.getAuth())
//  }
//  const signIn = ui_btn("sign in")
//  signIn.onclick = async () => {
//      await getUser()
//  }

