import { asset, Head } from "$fresh/runtime.ts";
import { useState } from "preact/hooks";
import { extname, join } from "path/posix.ts";
import { ComponentChild } from "preact";
import UpList from "./UpList.tsx";
import { extToIcon } from "../src/media.ts";
import natsort from "../src/natsort.ts";
import { encodePath } from "../util/util.ts";

function ListItem(props: {
  href: string;
  icon: string;
  children: ComponentChild;
}) {
  return (
    <li class="p-1 hover:bg-gray-400 transition-colors">
      <a class="flex gap-2" href={props.href}>
        <div class="bg-black dark:bg-white w-4 h-4" style={`mask: url(${asset(props.icon)})`}></div>  
        <p class="">{props.children}</p>
      </a>
    </li>
  );
}

export interface EntryInfo {
  name: string;
  isFile: boolean;
  isDirectory: boolean;
  isSymlink: boolean;
  size: number;
  lastModified?: Date;
}

interface DirListProps {
  path: string;
  files: EntryInfo[];
}
const natsortCompare = natsort();

function toSorted<T>(arr: T[], compareFn: (a:T,b:T) => number): T[]{
  const ret = Array.from(arr);
  ret.sort(compareFn);
  return ret;
}

export function DirList(props: DirListProps) {
  const data = props;
  const [files, setFiles] = useState(
    toSorted(data.files,(
      (a,b)=> natsortCompare(a.name,b.name)
      ))
    );

  return (
    <div>
      <UpList path={data.path}></UpList>
      <ul class="border-2 rounded-md">
        <li class="p-1 flex gap-2">
          <button class="flex" onClick={sortDir}>
            <img src={asset("/icon/sort-down.svg")} /> Sort Directory
          </button>
          <button class="flex" onClick={sortAlpha}>
            <img src={asset("/icon/sort-alpha-down.svg")} /> Sort Alphabet
          </button>
        </li>
        <ListItem
          key=".."
          href={`/dir/${encodePath(join(data.path, ".."))}/?pretty`}
          icon="/icon/back.svg"
        >
          ...
        </ListItem>
        {files.map((file) => (
          <ListItem
            key={file.name}
            href={`/dir/${
              encodePath(join(data.path, file.name))
            }${(file.isDirectory ? "/" : "")}?pretty`}
            icon={file.isDirectory
              ? "/icon/folder.svg"
              : extToIcon(extname(file.name))}
          >
            {file.name}
          </ListItem>
        ))}
      </ul>
    </div>
  );
  function sortDir() {
    // sort by directory first then by index
    const sorted_files = files.map((x, i) => ([x, i] as [EntryInfo, number]))
      .sort(
        ([a, ai], [b, bi]) => {
          if (a.isDirectory && !b.isDirectory) {
            return -1;
          } else if (!a.isDirectory && b.isDirectory) {
            return 1;
          } else {
            return ai - bi;
          }
        },
      );
    setFiles(sorted_files.map(([x, _]) => x));
  }
  function sortAlpha() {
    // sort by alphabet first then by index
    const sorted_files = files.map((x, i) => ([x, i] as [EntryInfo, number]))
      .sort(
        ([a, ai], [b, bi]) => {
          const ret = natsortCompare(a.name, b.name);
          if (ret === 0) {
            return ai - bi;
          } else {
            return ret;
          }
        },
      );
    setFiles(sorted_files.map(([x, _]) => x));
  }
}

export default function DirListIsland(props: DirListProps){
  return <DirList {...props}/>
}
