package api

import zio.*
import zio.http.*
import scala.io.Source

/** Landing page and static asset routes
  */
object LandingRoutes {

  private def loadResource(path: String): Option[String] =
    Option(getClass.getClassLoader.getResourceAsStream(path)).map { stream =>
      val content = Source.fromInputStream(stream, "UTF-8").mkString
      stream.close()
      content
    }

  private def serveLanding: ZIO[Any, Nothing, Response] =
    ZIO.succeed {
      loadResource("public/landing.html") match {
        case Some(html) =>
          Response(
            status = Status.Ok,
            headers = Headers(Header.ContentType(MediaType.text.html)),
            body = Body.fromString(html)
          )
        case None =>
          Response.text("Landing page not found").status(Status.InternalServerError)
      }
    }

  private def serveImage(filename: String): ZIO[Any, Nothing, Response] =
    ZIO.attemptBlocking {
      val path = s"public/assets/images/$filename"
      val stream = getClass.getClassLoader.getResourceAsStream(path)
      if (stream == null) {
        Response.notFound
      } else {
        val bytes = stream.readAllBytes()
        stream.close()
        val mediaType = if (filename.endsWith(".png")) MediaType.image.png
                       else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) MediaType.image.jpeg
                       else if (filename.endsWith(".svg")) MediaType.image.`svg+xml`
                       else if (filename.endsWith(".gif")) MediaType.image.gif
                       else MediaType.application.`octet-stream`
        Response(
          status = Status.Ok,
          headers = Headers(Header.ContentType(mediaType)),
          body = Body.fromChunk(Chunk.fromArray(bytes))
        )
      }
    }.catchAll(_ => ZIO.succeed(Response.notFound))

  val routes: Routes[Any, Response] =
    Routes(
      Method.GET / Root -> handler(serveLanding),
      Method.GET / "assets" / "images" / string("filename") -> handler { (filename: String, _: Request) =>
        serveImage(filename)
      }
    )

}
