import axios from "axios";
import { useEffect, useState } from "react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from "@/components/ui/table"
import {
    Sheet,
    SheetClose,
    SheetContent,
    SheetDescription,
    SheetFooter,
    SheetHeader,
    SheetTitle,
    SheetTrigger,
} from "@/components/ui/sheet"
import { z } from "zod";
import { Trash2 } from "lucide-react";
import RoleGate from "@/components/auth/role-gate";

interface UsersGroup {
    groupId: string
    groupName: string
    //userList: { id: number, username: string }[]
    //knownUsers: { id: number, username: string }[]
}

const ITEMS_PER_PAGE: number = 10;

const UserList = ({
    groupId,
    groupName,
    //userList,
    //knownUsers
}: UsersGroup) => {
    const [usersListOpen, setUsersListOpen] = useState(false)
    const [users, setUsers] = useState<{ id: number, username: string }[]>([])
    const [addedUsers, setAddedUsers] = useState<{ id: number, username: string }[]>([])
    const [deletedUsers, setDeletedUsers] = useState<{ id: number, username: string }[]>([])
    const [newUser, setNewUser] = useState<string>("")
    const [knownUsers, setKnownUsers] = useState<{ id: number, username: string }[]>([])
    const [error, setError] = useState<string | undefined>(undefined)
    const [page, setPage] = useState<number>(0)
    const [maxPages, setMaxPages] = useState<number>(1)


    useEffect(() => {
        axios.get('/api/settings/groups/chatters', {
            params: {
                groupId,
                page
            }
        }).then(d => {
            setUsers(d.data)
            setKnownUsers(d.data)
            setMaxPages(Math.ceil(d.data.length / ITEMS_PER_PAGE))
        })
    }, [groupId, page])

    function close() {
        setUsers([...users.filter(u => !addedUsers.find(a => a.id == u.id)), ...deletedUsers])
        setUsersListOpen(false)
    }

    const usernameSchema = z.string({
        required_error: "Name is required.",
        invalid_type_error: "Name must be a string"
    }).regex(/^[\w\-]{4,25}$/, "Invalid Twitch username.")

    function AddUsername() {
        setError(undefined)

        const nameValidation = usernameSchema.safeParse(newUser)
        if (!nameValidation.success) {
            setError(JSON.parse(nameValidation.error['message'])[0].message)
            return
        }

        if (users.find(u => u.username == newUser.toLowerCase())) {
            setError("Username is already in this group.")
            return;
        }

        let user = knownUsers.find(u => u.username == newUser.toLowerCase())
        if (!user) {
            axios.get('/api/settings/groups/twitchchatters', {
                params: {
                    logins: newUser
                }
            }).then(d => {
                if (!d.data)
                    return

                user = d.data[0]
                if (!user)
                    return

                if (deletedUsers.find(u => u.id == user!.id))
                    setDeletedUsers(deletedUsers.filter(u => u.id != user!.id))
                else
                    setAddedUsers([...addedUsers, user])
                setUsers([...users, user])
                setKnownUsers([...users, user])
                setNewUser("")
                setMaxPages(Math.ceil((users.length + 1) / ITEMS_PER_PAGE))
            }).catch(e => {
                setError("Username does not exist.")
            })
            return
        }

        if (deletedUsers.find(u => u.id == user!.id))
            setDeletedUsers(deletedUsers.filter(u => u.id != user!.id))
        else
            setAddedUsers([...addedUsers, user])
        setUsers([...users, user])
        setNewUser("")
        setMaxPages(Math.ceil((users.length + 1) / ITEMS_PER_PAGE))

        if (deletedUsers.find(u => u.id == user!.id)) {
            setAddedUsers(addedUsers.filter(u => u.username != newUser.toLowerCase()))
        }
    }

    function DeleteUser(user: { id: number, username: string }) {
        if (addedUsers.find(u => u.id == user.id)) {
            setAddedUsers(addedUsers.filter(u => u.id != user.id))
        } else {
            setDeletedUsers([...deletedUsers, user])
        }
        setUsers(users.filter(u => u.id != user.id))
    }

    function save() {
        setError(undefined)

        if (addedUsers.length > 0) {
            axios.post("/api/settings/groups/chatters", {
                groupId,
                users: addedUsers
            }).then(d => {
                setAddedUsers([])

                if (deletedUsers.length > 0)
                    axios.delete("/api/settings/groups/chatters", {
                        params: {
                            groupId,
                            ids: deletedUsers.map(i => i.id.toString()).reduce((a, b) => a + ',' + b)
                        }
                    }).then(d => {
                        setDeletedUsers([])
                    }).catch(() => {
                        setError("Something went wrong.")
                    })
            }).catch(() => {
                setError("Something went wrong.")
            })
            return
        }

        if (deletedUsers.length > 0)
            axios.delete("/api/settings/groups/chatters", {
                params: {
                    groupId,
                    ids: deletedUsers.map(i => i.id.toString()).reduce((a, b) => a + ',' + b)
                }
            }).then(d => {
                setDeletedUsers([])
            }).catch(() => {
                setError("Something went wrong.")
            })
    }

    return (
        <Sheet>
            <SheetTrigger asChild>
                <Button
                    className="ml-3 mr-3 align-middle"
                    onClick={() => setUsersListOpen(true)}>
                    Users
                </Button>
            </SheetTrigger>
            <SheetContent className="w-[700px]">
                <SheetHeader>
                    <SheetTitle>Edit group - {groupName}</SheetTitle>
                    <SheetDescription>
                        Make changes to this group&#39;s list of users.
                    </SheetDescription>
                </SheetHeader>
                {!!error &&
                    <p className="text-red-500">{error}</p>
                }
                <div className="grid gap-4 py-4">
                    <div className="grid grid-cols-4 items-center gap-4">
                        <Label htmlFor="name" className="text-right">
                            Username
                        </Label>
                        <Input
                            id="name"
                            value={newUser}
                            type="text"
                            onChange={e => setNewUser(e.target.value)}
                            className="col-span-3" />

                        <Button
                            className="bg-white"
                            onClick={() => AddUsername()}>
                            Add
                        </Button>
                    </div>
                </div>
                <hr className="mt-4" />
                <Table>
                    <TableHeader>
                        <TableRow>
                            <RoleGate roles={['ADMIN']}><TableHead>Id</TableHead></RoleGate>
                            <TableHead>Username</TableHead>
                            <TableHead>Delete</TableHead>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {users.length ? (
                            users.slice(ITEMS_PER_PAGE * page, ITEMS_PER_PAGE * (page + 1)).map((user) => (
                                <TableRow
                                    key={user.id}>
                                    <RoleGate roles={['ADMIN']}><TableCell colSpan={1} className="text-xs">{user.id}</TableCell></RoleGate>
                                    <TableCell colSpan={1}>{user.username}</TableCell>
                                    <TableCell>
                                        <Button
                                            className="bg-red-500 h-9"
                                            onClick={() => DeleteUser(user)}>
                                            <Trash2 />
                                        </Button>
                                    </TableCell>
                                </TableRow>
                            ))
                        ) : (
                            <TableRow>
                                <TableCell
                                    colSpan={3}
                                    className="h-24 text-center">
                                    No results.
                                </TableCell>
                            </TableRow>
                        )}
                    </TableBody>
                </Table>
                <SheetFooter>
                    <SheetClose asChild>
                        <Button onClick={() => save()} type="submit">Save changes</Button>
                    </SheetClose>
                    <SheetClose asChild>
                        <Button onClick={() => close()} type="submit">Close</Button>
                    </SheetClose>
                </SheetFooter>
            </SheetContent>
        </Sheet>
    );
}

export default UserList;