import { CopyButton } from "@/app/components/copy-button";
import { ErrorCard } from "@/app/components/error-card";
import { LookupServer } from "@/app/components/server/lookup-server";
import { ServerView } from "@/app/components/server/server-view";
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from "@/app/components/ui/context-menu";
import { Colors } from "@/common/colors";
import { generateEmbed } from "@/common/embed";
import { isValidServer } from "@/common/server";
import { capitalizeFirstLetter } from "@/common/string-utils";
import {
  CachedBedrockMinecraftServer,
  CachedJavaMinecraftServer,
  McUtilsAPIError,
  ServerPlatform,
  getServer,
} from "mcutils-library";
import { Metadata, Viewport } from "next";
import { ReactElement } from "react";
import config from "../../../../../../config.json";

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 | null,
  server: CachedJavaMinecraftServer | CachedBedrockMinecraftServer | undefined,
): string | undefined {
  if (server == null || platform === ServerPlatform.Bedrock) {
    return config.apiUrl + "/server/icon/fallback";
  }
  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 generateViewport({ params: { platform, hostname } }: Params): Promise<Viewport> {
  const validPlayer = await isValidServer(platform, hostname);
  return {
    themeColor: validPlayer ? Colors.green : Colors.red,
  };
}

export async function generateMetadata({ params: { platform, hostname } }: Params): Promise<Metadata> {
  if (!checkPlatform(platform)) {
    // Invalid platform
    return generateEmbed({
      title: "Server Not Found",
      description: "Invalid platform",
    });
  }
  if (!hostname || hostname.length === 0) {
    // No hostname
    return generateEmbed({
      title: "Server Lookup",
      description: `Click to lookup a ${capitalizeFirstLetter(platform)} server.`,
    });
  }

  try {
    const server = await getServer(platform, hostname);
    const { hostname: serverHostname, players } = server as CachedJavaMinecraftServer | CachedBedrockMinecraftServer;

    const favicon = getFavicon(platform, server);

    let description = `Hostname: ${serverHostname}\n`;
    description += `${players.online}/${players.max} players online\n\n`;
    description += "Click to view more information about the server.";

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

export default async function Page({ params: { platform, hostname } }: Params): Promise<ReactElement> {
  let error: string | undefined = undefined; // The error to display
  let server: CachedJavaMinecraftServer | CachedBedrockMinecraftServer | undefined = undefined; // The server to display
  let invalidPlatform: boolean = !checkPlatform(platform); // Whether the platform is invalid
  let favicon: string | undefined; // The server's favicon

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

  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 currentPlatform={platform.toLocaleLowerCase()} />
      </div>

      {error && <ErrorCard message={error} />}
      {server != null && (
        <ContextMenu>
          <ContextMenuTrigger>
            <ServerView server={server} favicon={favicon} />
          </ContextMenuTrigger>
          <ContextMenuContent className="flex flex-col">
            <CopyButton content={server.hostname}>
              <ContextMenuItem>Copy Server Hostname</ContextMenuItem>
            </CopyButton>
            {favicon && (
              <CopyButton content={favicon}>
                <ContextMenuItem>Copy Server Favicon URL</ContextMenuItem>
              </CopyButton>
            )}
          </ContextMenuContent>
        </ContextMenu>
      )}
    </div>
  );
}
