import { ComponentType, useRef, useState } from "react"
import { useEffect } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { randomColor } from "https://framer.com/m/framer/utils.js@^0.9.0"
import * as SupabaseJs from "https://jspm.dev/@supabase/supabase-js@rc"
import _ from "lodash"
// Learn more: https://www.framer.com/docs/guides/overrides/

export const useStore = createStore({
    background: "#0099FF",
    dburl: "https://qsxfdqhsuyovskknxkaj.supabase.co",
    dbAPIKey:
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTY0MDM3ODAxMCwiZXhwIjoxOTU1OTU0MDEwfQ.STNbut59AMoiD6Zd6O4oi0NJ__8fKahZitQPnWffK0E",
    supabaseObj: null,
    roomName: "sandbox-room-1",
    objects: {
        red: { x: 0, y: 0 },
        yellow: { x: 0, y: 0 },
    },
    objectName: "",
    channelRef: null,
})

export function init(Component): ComponentType {
    return (props) => {
        const [store, setStore] = useStore()
        var ref = useRef()
        useEffect(() => {
            const supabase = SupabaseJs.createClient(
                store.dburl,
                store.dbAPIKey
            )
            setStore({ supabaseObj: supabase })

            console.log("supabase connected: ", supabase)

            var name = new URLSearchParams(window.location.search).getAll("id")

            setStore({ objectName: name[0], channelRef: ref })
        }, [])

        return <Component {...props} />
    }
}

export function addDrag(Component): ComponentType {
    return (props) => {
        const [store, setStore] = useStore()
        var channel
        var ref = useRef()
        const subscribeToRoom = () => {
            // The name of the channel can be set to any string.
            // Set the same name across both the broadcasting and receiving clients.
            store.channelRef.current = store.supabaseObj.channel(
                store.roomName,
                {
                    configs: {
                        broadcast: { ack: true },
                    },
                }
            )

            // listen to broadcasts
            console.log(channel)
            store.channelRef.current.subscribe(async (status) => {
                console.log(status)
                if (status === "SUBSCRIBED") {
                    store.channelRef.current.on(
                        "broadcast",
                        { event: "location" },
                        (payload) => {
                            console.log(payload)
                            var obj = _.cloneDeep(store.objects)
                            obj[payload.payload.name] = {
                                x: payload.payload.x,
                                y: payload.payload.y,
                            }
                            setStore({ objects: obj })
                        }
                    )
                    console.log("Status: ", status)
                }
            })
        }

        const sendDrag = async (event, info) => {
            console.log(store.channelRef.current)
            if (store.channelRef.current) {
                var diffX = Math.abs(
                    ref.current.getBoundingClientRect().left - info.point.x
                )
                var diffY = Math.abs(
                    ref.current.getBoundingClientRect().top - info.point.y
                )

                const status = await store.channelRef.current.send({
                    type: "broadcast",
                    event: "location",
                    payload: {
                        x: ref.current.getBoundingClientRect().left,
                        y: ref.current.getBoundingClientRect().top,
                        name: store.objectName,
                    },
                })
                console.log(status)
            }
        }

        useEffect(() => {
            if (store.supabaseObj !== null) {
                subscribeToRoom()
            }
        }, [store.supabaseObj])

        return (
            <Component
                ref={ref}
                {...props}
                whileHover={{ scale: 1.05 }}
                drag
                whileDrag={{ scale: 1.1 }}
                dragMomentum={false}
                onDrag={(event, info) => sendDrag(event, info)}
            />
        )
    }
}

export function setRedPosition(Component): ComponentType {
    return (props) => {
        const [store, setStore] = useStore()
        const [pos, setPos] = useState({ x: 0, y: 0 })
        useEffect(() => {
            console.log(store.objects.red)
            setPos(store.objects.red)
        }, [store.objects.red])

        return (
            <Component
                {...props}
                whileHover={{ scale: 1.05 }}
                animate={{ x: pos.x, y: pos.y }}
            />
        )
    }
}
