import { FunctionComponent } from "preact";
import { Content } from "../../components/Content.tsx";
import { SERVER_STATE } from "../../state/serverState.ts";
import { FileUploader } from "../../islands/fileUploader.tsx";
import { Handlers, PageProps } from "$fresh/server.ts";
import { ensureFile } from "$std/fs/ensure_file.ts";
import { ensureDir } from "$std/fs/ensure_dir.ts";
import { Button } from "../../components/Button.tsx";

export const handler: Handlers = {
  async POST(req, _ctx) {
    const formData = await req.formData();
    const filePath = formData.get("filePath") as string;
    if (typeof filePath !== "string") {
      throw "File path not included in mod enable/disable";
    }

    if (formData.get("delete")) {
      await Deno.remove(filePath);
      return Response.redirect(req.url);
    }

    const fileName = filePath.split("/").at(-1);

    if (!fileName) throw "Unable to infer filename in mod enable/disable";

    try {
      await Deno.lstat(filePath);
    } catch {
      return Response.redirect(req.url);
    }

    if (filePath.includes("disabled")) {
      await ensureFile("./server/mods/" + fileName);
      await Deno.rename(filePath, "./server/mods/" + fileName);
    } else {
      await ensureFile("./server/disabled-mods/" + fileName);
      await Deno.rename(filePath, "./server/disabled-mods/" + fileName);
    }

    return Response.redirect(req.url);
  },
  async GET(_, ctx) {
    const activeMods: string[] = [];
    const disabledMods: string[] = [];
    if (
      SERVER_STATE.serverType !== "unset" &&
      SERVER_STATE.serverType !== "vanilla"
    ) {
      for await (const fileEntry of Deno.readDir("./server/mods")) {
        if (fileEntry.isFile) {
          activeMods.push(fileEntry.name);
        }
      }
      await ensureDir("./server/disabled-mods");
      for await (const fileEntry of Deno.readDir("./server/disabled-mods")) {
        if (fileEntry.isFile) {
          disabledMods.push(fileEntry.name);
        }
      }
    }

    return ctx.render({
      activeMods,
      disabledMods,
    });
  },
};

export default function ModsFolder(
  { url, data: { activeMods, disabledMods } }: PageProps<
    { activeMods: string[]; disabledMods: string[] }
  >,
) {
  return (
    <div className="container p-8 flex flex-col gap-8">
      <Content>
        <h2 class="font-pixel text-xl">Active Mods</h2>
        <FileUploader path="./server/mods">
          <div class="min-h-[100px]">
            <div className="relative grid lg:grid-cols-3 gap-8">
              {!activeMods.length && (
                <div class="absolute place-self-center">
                  Drop files here to upload
                </div>
              )}
              {activeMods.map((f) => (
                <div class="flex justify-between">
                  <div class="flex gap-2 items-center">
                    <FileIcon fileName={f} />
                    {f}
                  </div>
                  <div class="flex gap-2">
                    <form action={url.pathname} method="POST">
                      <input
                        type="hidden"
                        name="filePath"
                        value={"./server/mods/" + f}
                      />
                      <Button type="submit">Disable</Button>
                    </form>
                    <form action={url.pathname} method="POST">
                      <input
                        type="hidden"
                        name="filePath"
                        value={"./server/disabled-mods/" + f}
                      />
                      <input
                        type="hidden"
                        name="delete"
                        value="true"
                      />
                      <Button color="fire" type="submit">
                        <i class="fas fa-trash"></i>
                      </Button>
                    </form>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </FileUploader>
      </Content>
      <Content>
        <h2 class="font-pixel text-xl">Disabled Mods</h2>
        <FileUploader path="./server/disabled-mods">
          <div class="min-h-[100px]">
            <div className="relative grid lg:grid-cols-3 gap-8">
              {!disabledMods.length && (
                <div class="absolute place-self-center">
                  Drop files here to upload
                </div>
              )}
              {disabledMods.map((f) => (
                <div class="flex justify-between">
                  <div class="flex gap-2 items-center">
                    <FileIcon fileName={f} />
                    {f}
                  </div>
                  <div class="flex gap-2">
                    <form action={url.pathname} method="POST">
                      <input
                        type="hidden"
                        name="filePath"
                        value={"./server/disabled-mods/" + f}
                      />
                      <Button type="submit">Enable</Button>
                    </form>
                    <form action={url.pathname} method="POST">
                      <input
                        type="hidden"
                        name="filePath"
                        value={"./server/disabled-mods/" + f}
                      />
                      <input
                        type="hidden"
                        name="delete"
                        value="true"
                      />
                      <Button color="fire" type="submit">
                        <i class="fas fa-trash"></i>
                      </Button>
                    </form>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </FileUploader>
      </Content>
    </div>
  );
}

const FileIcon: FunctionComponent<{ fileName: string }> = ({ fileName }) => {
  let icon;
  switch (fileName.split(".").at(-1)) {
    case "jar":
      icon = "fab fa-java";
      break;
    case "tmp":
    case "temp":
      icon = "fas fa-ghost";
      break;
    case "png":
    case "jpg":
    case "jpeg":
    case "webp":
      icon = "fas fa-image";
      break;
    default:
      icon = "fas fa-file";
  }

  return <i class={icon}></i>;
};
