"use client";

import axios from "axios";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { useRouter } from "next/navigation";
import { v4 } from "uuid";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Input } from "@/components/ui/input";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { env } from "process";

export interface Connection {
    name: string
    type: string
    clientId: string
    scope: string
    expiresAt: Date
    remover: (name: string) => void
}

const AUTHORIZATION_DATA: { [service: string]: { type: string, endpoint: string, grantType: string, scopes: string[], redirect: string } } = {
    'nightbot': {
        type: 'nightbot',
        endpoint: 'https://api.nightbot.tv/oauth2/authorize',
        grantType: 'token',
        scopes: ['song_requests', 'song_requests_queue', 'song_requests_playlist'],
        redirect: 'https://tomtospeech.com/connection/authorize'
    },
    'twitch': {
        type: 'twitch',
        endpoint: 'https://id.twitch.tv/oauth2/authorize',
        grantType: 'token',
        scopes: [
            'chat:read',
            'bits:read',
            'channel:read:polls',
            'channel:read:predictions',
            'channel:read:subscriptions',
            'channel:read:vips',
            'moderator:read:blocked_terms',
            'chat:read',
            'channel:moderate',
            'channel:read:redemptions',
            'channel:manage:redemptions',
            'channel:manage:predictions',
            'user:read:chat',
            'channel:bot',
            'moderator:read:followers',
            'channel:read:ads',
            'moderator:read:chatters',
        ],
        redirect: 'https://tomtospeech.com/connection/authorize'
    },
    // 'twitch tts bot': {
    //     type: 'twitch',
    //     endpoint: 'https://id.twitch.tv/oauth2/authorize',
    //     grantType: 'token',
    //     scopes: [
    //         'chat:read',
    //         'bits:read',
    //         'channel:read:polls',
    //         'channel:read:predictions',
    //         'channel:read:subscriptions',
    //         'channel:read:vips',
    //         'moderator:read:blocked_terms',
    //         'chat:read',
    //         'channel:moderate',
    //         'channel:read:redemptions',
    //         'channel:manage:redemptions',
    //         'channel:manage:predictions',
    //         'user:read:chat',
    //         'channel:bot',
    //         'moderator:read:followers',
    //         'channel:read:ads',
    //         'moderator:read:chatters',
    //     ],
    //     redirect: 'https://tomtospeech.com/connection/authorize'
    // }
}

function AddOrRenew(name: string, type: string | undefined, clientId: string, router: AppRouterInstance) {
    if (type === undefined)
        return
    if (!(type in AUTHORIZATION_DATA))
        return

    console.log(type)
    const data = AUTHORIZATION_DATA[type]
    const state = v4()
    const clientIdUpdated = type == 'twitch tts bot' ? process.env.NEXT_PUBLIC_TWITCH_TTS_CLIENT_ID : clientId
    axios.post("/api/connection/prepare", {
        name: name,
        type: data.type,
        clientId: clientIdUpdated,
        grantType: data.grantType,
        state: state
    }).then(_ => {
        const url = data.endpoint + '?client_id=' + clientIdUpdated + '&redirect_uri=' + data.redirect + '&response_type=' + data.grantType
            + '&scope=' + data.scopes.join('%20') + '&state=' + state + '&force_verify=true'
        router.push(url)
    })
}

export const ConnectionElement = ({
    name,
    type,
    clientId,
    expiresAt,
    remover,
}: Connection) => {
    const router = useRouter()
    const expirationHours = (new Date(expiresAt).getTime() - new Date().getTime()) / 1000 / 60 / 60
    const expirationDays = expirationHours / 24

    function Delete() {
        axios.delete("/api/connection?name=" + name)
            .then(d => {
                remover(d.data.data.name)
            })
    }

    return (
        <div
            className="bg-green-300 p-3 border-2 border-green-400 rounded-lg flex text-black m-1">
            <div
                className="justify-between flex-1 font-bold text-xl">
                {name}
                <div className="text-base font-normal">
                    {expirationDays > 1 && Math.floor(expirationDays) + " days - " + type}
                    {expirationDays <= 1 && Math.floor(expirationHours) + " hours - " + type}
                </div>
            </div>

            <div
                className="float-right align-middle flex flex-row items-center">
                <Button
                    className="bg-blue-500 mr-3"
                    onClick={() => AddOrRenew(name, type, clientId, router)}>
                    Renew
                </Button>
                <Button
                    className="bg-red-500"
                    onClick={Delete}>
                    Delete
                </Button>
            </div>
        </div>
    );
}

export const ConnectionAdderElement = () => {
    const router = useRouter()
    const [name, setName] = useState<string>('')
    const [type, setType] = useState<string | undefined>(undefined)
    const [clientId, setClientId] = useState('')
    const [open, setOpen] = useState(false)

    return (
        <div
            className="bg-green-300 p-3 border-2 border-green-300 rounded-lg flex  m-1">
            <div
                className="justify-between flex-1">
                <Popover
                    open={open}
                    onOpenChange={setOpen}>
                    <PopoverTrigger asChild>
                        <Button
                            variant="outline"
                            role="combobox"
                            aria-expanded={open}
                            className="w-[120px] justify-between"
                        >{!type ? "Select service..." : type}</Button>
                    </PopoverTrigger>
                    <PopoverContent>
                        <Command>
                            <CommandInput
                                placeholder="Filter services..."
                                autoFocus={true} />
                            <CommandList>
                                <CommandEmpty>No action found.</CommandEmpty>
                                <CommandGroup>
                                    {Object.keys(AUTHORIZATION_DATA).map((authType: string) => (
                                        <CommandItem
                                            value={authType}
                                            key={authType}
                                            onSelect={(value) => {
                                                setType(authType)
                                                setOpen(false)
                                            }}>
                                            {authType}
                                        </CommandItem>
                                    ))}
                                </CommandGroup>
                            </CommandList>
                        </Command>
                    </PopoverContent>
                </Popover>
                <Input
                    className='w-[200px] inline m-1'
                    placeholder="Name"
                    value={name}
                    onChange={e => setName(e.target.value.toLowerCase())} />
                {!!type && type != 'twitch tts bot' &&
                    <Input
                        className='w-[250px] m-1'
                        placeholder="Client Id"
                        value={clientId}
                        onChange={e => setClientId(e.target.value)} />
                }
            </div>
            <div
                className="float-right flex flex-row items-center">
                <Button
                    className="bg-green-500"
                    onClick={() => AddOrRenew(name, type, clientId, router)}>
                    Add
                </Button>
            </div>
        </div>
    );
}