import { Card } from "@/app/components/card";
import { ErrorCard } from "@/app/components/error-card";
import { LookupServer } from "@/app/components/server/lookup-server";
import { generateEmbed } from "@/common/embed";
import { formatNumber } from "@/common/number-utils";
import { capitalizeFirstLetter } from "@/common/string-utils";
import {
  CachedBedrockMinecraftServer,
  CachedJavaMinecraftServer,
  McUtilsAPIError,
  ServerPlatform,
  getServer,
} from "mcutils-library";
import { Metadata } from "next";
import Image from "next/image";

type Params = {
  params: {
    platform: ServerPlatform;
    hostname: string;
  };
};

/**
 * Gets the favicon for a server
 *
 * @param platform the platform of the server
 * @param server the server to get the favicon from
 * @returns the favicon url or null if there is no favicon
 */
function getFavicon(
  platform: ServerPlatform,
  server: CachedJavaMinecraftServer | CachedBedrockMinecraftServer
): string | undefined {
  if (platform === ServerPlatform.Bedrock) {
    return undefined;
  }
  server = server as CachedJavaMinecraftServer;
  return server.favicon && server.favicon.url;
}

/**
 * Checks if a platform is valid
 *
 * @param platform the platform to check
 * @returns true if the platform is valid, false otherwise
 */
function checkPlatform(platform: ServerPlatform): boolean {
  return platform === ServerPlatform.Java || platform === ServerPlatform.Bedrock;
}

export async function generateMetadata({ params: { platform, hostname } }: Params): Promise<Metadata> {
  try {
    if (checkPlatform(platform) === false) {
      return generateEmbed({
        title: "Server Not Found",
        description: "Invalid platform",
      });
    }
    const server = await getServer(platform, hostname);
    const { hostname: serverHostname, players } = server as CachedJavaMinecraftServer | CachedBedrockMinecraftServer;

    const favicon = server ? getFavicon(platform, server) : undefined;

    const description = `Hostname: ${serverHostname}\n${players.online}/${players.max} players online\n\nClick to view more information about the player.`;

    return generateEmbed({
      title: `${serverHostname}`,
      description: description,
      image: favicon,
    });
  } catch (err) {
    return generateEmbed({
      title: "Server Not Found",
      description: (err as McUtilsAPIError).message,
    });
  }
}

export default async function Page({ params: { platform, hostname } }: Params): Promise<JSX.Element> {
  let error: string | undefined = undefined; // The error to display
  let server: CachedJavaMinecraftServer | CachedBedrockMinecraftServer | undefined = undefined; // The server to display
  let invalidPlatform = checkPlatform(platform) === false;

  // Try and get the player to display
  try {
    console.log(platform);
    if (invalidPlatform) {
      error = "Invalid platform"; // Set the error message
    } else {
      server = platform && hostname ? await getServer(platform, hostname) : undefined;
    }
  } catch (err) {
    error = (err as McUtilsAPIError).message; // Set the error message
  }

  const favicon = server ? getFavicon(platform, server) : undefined;

  return (
    <div className="h-full flex flex-col items-center">
      <div className="mb-4 text-center">
        <h1 className="text-xl">Lookup a {invalidPlatform ? "" : capitalizeFirstLetter(platform)} Server</h1>
        <p>You can enter a server hostname to get information about the server.</p>

        <LookupServer />
      </div>

      {error && <ErrorCard message={error} />}
      {server != null && (
        <Card className="w-max xs:w-fit">
          <div className="flex gap-4 flex-col">
            <div className="flex gap-4 flex-col xs:flex-row">
              {favicon && (
                <div className="flex justify-center xs:justify-start">
                  <Image
                    className="w-[64px] h-[64px]"
                    src={favicon}
                    width={64}
                    height={64}
                    quality={100}
                    alt="The server's favicon"
                  />
                </div>
              )}

              <div className="flex flex-col">
                <h2 className="text-xl text-primary">{server.hostname}</h2>
                <div>
                  <p>
                    Players online: {formatNumber(server.players.online)}/{formatNumber(server.players.max)}
                  </p>
                </div>
              </div>
            </div>

            <div className="bg-background rounded-lg p-2 text-sm xs:text-lg">
              {server.motd.html.map((line, index) => {
                return <p key={index} dangerouslySetInnerHTML={{ __html: line }}></p>;
              })}
            </div>
          </div>
        </Card>
      )}
    </div>
  );
}
