import {
  Context,
  RouteHandler,
  RouteInitWithHandler,
  Router,
} from "@oak/acorn";
import { db_setup, select_closest } from "./db.ts";
import { DatabaseSync } from "node:sqlite";
import { json_mime_add } from "./utils.ts";
import { assert } from "@std/assert";

const root_url = Deno.env.get("ROOT_URL");

const db = new DatabaseSync(":memory:");
db_setup(db);

const router = new Router();

const trip_list = (async () => {
  let lst = [];
  // could be a static file but I'm lazy
  for await (const dirEntry of Deno.readDir("trips")) {
    lst.push(dirEntry.name);
  }
  lst = lst.map((name) => URL.parse(root_url + `/${name}`));
  return lst;
})();

router.get(
  "/trips",
  async (_) => {
    return new Response(JSON.stringify(await trip_list));
  },
);
router.get(
  "/trips/:id",
  async (ctx) => {
    const { params: { id } } = ctx;
    try {
      const bytes = await Deno.readFile(`trips/${id}`);
      const headers = new Headers();
      json_mime_add(headers);
      return new Response(bytes, { headers });
    } catch (_) {
      return new Response("", { status: 404 });
    }
  },
);
router.get(
  "/stops/:id",
  async (ctx) => {
    const { params: { id } } = ctx;
    try {
      const bytes = await Deno.readFile(`stops/${id}`);
      const headers = new Headers();
      json_mime_add(headers);
      return new Response(bytes, { headers });
    } catch (_) {
      return new Response("", { status: 404 });
    }
  },
);

const hub =
  (db.prepare("select href from hub_stops where hub='BCT';").get() as {
    href: string;
  }).href;
assert(hub !== undefined, "hub please");
router.get(
  "/path",
  async (ctx) => {
    const query = await ctx.queryParams();
    if (!query) return new Response("no query params", { status: 400 });

    const s_lattitude = query["start_lat"];
    const s_longitude = query["start_lon"];
    const e_lattitude = query["end_lat"];
    const e_longitude = query["end_lon"];
    const _time = query["time"];

    if (
      typeof s_lattitude != "string" || typeof s_longitude != "string" ||
      typeof e_lattitude != "string" || typeof e_longitude != "string" ||
      typeof _time != "string"
    ) {
      return new Response("missing or invalid query params", { status: 400 });
    }

    const start = select_closest(db, {
      lat: Number(s_lattitude),
      lon: Number(s_longitude),
    }, 1);

    const mid = hub;

    const end = select_closest(db, {
      lat: Number(e_lattitude),
      lon: Number(e_longitude),
    }, 1);
    const headers = new Headers();
    json_mime_add(headers);
    return new Response(
      `{
        "path": [
            ${start},
            ${mid},
            ${end}
        ]
    }`,
      { headers },
    );
  },
);

router.listen({ hostname: "0.0.0.0", port: 80 });
