import { getColor } from "@/lib/colors"
import { env } from "@/lib/env/server"
import { getGuild } from "@/lib/hypixel/api/guild"
import { getUuid } from "@/lib/hypixel/api/mojang"
import { Guild } from "@/lib/schema/guild"
import { cn, parseSearchParams } from "@/lib/utils"
import { Loader2Icon, ShieldAlert } from "lucide-react"
import { Metadata } from "next"
import { ReactNode, Suspense } from "react"
import z from "zod"
import { GuildPageLoadText } from "./_client"
import { GuildMembers } from "./_components/members"
import Sidebar from "./_components/sidebar"

export async function generateMetadata({ params, searchParams }: PageProps<"/guild/[value]">): Promise<Metadata> {
    const { value } = await params
    const ptype = parseSearchParams(await searchParams).getValue("type")
    const { data: type } = z.literal("id").or(z.literal("name")).or(z.literal("player")).default("player").safeParse(ptype)

    switch (type) {
        case "id":
        case "name":
            const g = await getGuild(value, type)
            return { title: g?.name !== undefined ? `${g.name} Guild` : "Unknown" }
        case "player":
        case undefined:
            const p = await getUuid(value)
            return { title: p !== null ? `${p.name}'s Guild` : "Player not in Guild" }
        default:
            throw new Error(`Unknown type: ${type satisfies never}`)
    }
}

export default function GuildPage({ params, searchParams }: PageProps<"/guild/[value]">) {
    const maintenance = env.MAINTENANCE_MODE

    if (maintenance) {
        return (
            <div className="flex flex-col gap-2 justify-center items-center h-screen">
                <ShieldAlert className="size-30" />
                <h1 className="text-xl">Not available right now. This is just so I could have a front page for Hypixel Production API Key.</h1>
            </div>
        )
    }

    return (
        <Suspense
            fallback={
                <div className="flex flex-col justify-center items-center h-screen">
                    <Loader2Icon className="animate-spin size-30" />
                    <GuildPageLoadText />
                </div>
            }
        >
            <SuspendedPage params={params} searchParams={searchParams} />
        </Suspense>
    )
}

async function SuspendedPage({ params, searchParams }: Pick<PageProps<"/guild/[value]">, "params" | "searchParams">) {
    const { value } = await params
    const ptype = parseSearchParams(await searchParams).getValue("type")
    const { data: type } = z.literal("id").or(z.literal("name")).or(z.literal("player")).default("player").safeParse(ptype)

    let guild: Guild["guild"] | null = null
    let component: ReactNode | null = null

    switch (type) {
        case "id":
            guild = await getGuild(value, type)
            component = (
                <div className="flex flex-col items-center min-h-screen">
                    <h1 className="pt-30">{`The guild with the id ${value} doesn't exist`}</h1>
                </div>
            )
            break
        case "name":
            guild = await getGuild(value, type)
            component = (
                <div className="flex flex-col items-center min-h-screen">
                    <h1 className="pt-30">{`The guild with the name ${value} doesn't exist`}</h1>
                </div>
            )
            break
        case "player":
        case undefined:
            const uuid = await getUuid(value)
            if (!uuid) {
                return (
                    <div className="flex flex-col items-center min-h-screen">
                        <h1 className="pt-30">Player not found</h1>
                    </div>
                )
            }
            guild = await getGuild(uuid.id, type)
            component = (
                <div className="flex flex-col items-center min-h-screen">
                    <h1 className="pt-30">{`${uuid.name} is not in a guild or has not logged on to hypixel`}</h1>
                </div>
            )
            break
    }

    if (!guild) return component

    return (
        <div className="flex flex-col items-center pb-5 pt-30">
            <div className="flex gap-2 items-center">
                <h1 className="text-4xl font-bold sm:text-5xl text-shadow-lg">
                    <span className={cn(getColor(guild.tagColor, "text", "gray"))}>{guild.name}</span>
                </h1>
            </div>
            <div className="flex flex-col gap-6 px-6 pb-4 mt-8 w-full max-w-7xl md:flex-row">
                <Sidebar guild={guild} />
                <div className="mx-auto space-y-4 w-full lg:mx-0 lg:w-3/4 max-w-120 md:max-w-7/10">
                    <GuildMembers members={guild.members} ranks={guild.ranks} />
                </div>
            </div>
        </div>
    )
}
