defmodule BrightWeb.Router do
  use BrightWeb, :router

  import Oban.Web.Router
  import Redirect

  import BrightWeb.AuthController,
    only: [
      fetch_current_user: 2,
      require_admin_user: 2,
      require_authenticated_user: 2,
      require_patron_tier_1: 2
    ]

  pipeline :browser do
    plug(:accepts, ["html", "json", "txt"])
    plug(:fetch_session)
    plug(:fetch_live_flash)
    plug(:fetch_current_user)
    plug(:put_root_layout, html: {BrightWeb.Layouts, :root})
    plug(:protect_from_forgery)
    plug(:put_secure_browser_headers)
  end

  pipeline :api do
    plug(:accepts, ["json"])
  end

  scope "/auth", BrightWeb do
    pipe_through(:browser)

    live_session :auth_login, on_mount: {BrightWeb.AuthController, :current_user} do
      live("/login", SignInLive, :index)
    end

    get("/logout", AuthController, :delete)
    get("/:provider", AuthController, :request)
    get("/:provider/callback", AuthController, :callback)
    post("/:provider/callback", AuthController, :callback)
  end

  ## tier 1 protected routes
  scope "/", BrightWeb do
    pipe_through [:browser, :require_authenticated_user, :require_patron_tier_1]

    resources("/vtubers", VtuberController, only: [:new, :create, :edit, :update])
  end

  ## admin protected routes
  ## this section needs to be above the unprotected routes,
  ## so routes like "/streams/new" take precedence.
  scope "/", BrightWeb do
    pipe_through [:browser, :require_admin_user]
    # pipe_through [:browser]

    resources("/streams", StreamController, only: [:new, :create, :edit, :update, :delete])

    # I think there is something faulty with how I'm calling these nested routes
    # # get "/vods/new", VodController, :new
    # # post "/vods", VodController, :create
    # # delete "/vods/:id", VodController, :delete
    # # get "/vods/:id/edit", VodController, :edit
    # resources "/vods",  StreamController, only: [:new, :create, :edit, :update, :delete]

    # resources "/vt", VtuberController do
    #   get "/vods/new", VodController, :new
    #   post "/vods", VodController, :create
    #   get "/vtubers/:id/edit", VtuberController, :edit
    # end

    # resources "/vtubers", VtuberController do
    #   get "/new", VtuberController, :new
    #   post "/", VtuberController, :create
    #   get "/vods/new", VodController, :new
    #   post "/vods", VodController, :create
    #   get "/vtubers/:id/edit", VtuberController, :edit
    # end

    resources("/vods", VodController, only: [:create, :new, :edit, :update, :delete])
    resources("/vtubers", VtuberController, only: [:delete])

    resources("/tags", TagController, only: [:new, :create, :edit, :update, :delete])

    resources("/torrents", TorrentController, only: [:new, :create, :edit, :update, :delete])

    resources("/platforms", PlatformController, only: [:new, :create, :edit, :update, :delete])

    resources("/platform_aliases", PlatformAliasController,
      only: [:new, :create, :edit, :update, :delete]
    )

    oban_dashboard("/oban")
  end

  ## tier 0 users can access these routes
  scope "/", BrightWeb do
    pipe_through(:browser)

    get("/", PageController, :home)
    get("/patrons", PatronController, :index)
    get("/about", PageController, :about)
    get("/goals", PageController, :about)
    get("/api", PageController, :api)

    resources("/torrents", TorrentController, only: [:index, :show])

    get("/streams", StreamController, :index)
    get("/streams/:id", StreamController, :show)

    get("/vods/:id", VodController, :show)
    get("/vods", VodController, :index)

    resources("/tags", TagController, only: [:index, :show])

    get("/platforms", PlatformController, :index)
    get("/platforms/:id", PlatformController, :show)

    get("/platform_aliases", PlatformAliasController, :index)
    get("/platform_aliases/:id", PlatformAliasController, :show)

    resources("/vtubers", VtuberController, only: [:index, :show])

    resources "/vt", VtuberController do
      get("/vods", VodController, :index)
      get("/vods/:id", VodController, :show)
    end

    live_session :authenticated,
      on_mount: [{BrightWeb.AuthController, :ensure_authenticated}] do
      live("/profile", ProfileLive)
      live("/uploads/new", UploadLive.Index, :index)
    end

    resources("/uploads", UploadController, only: [:show, :index, :delete])
  end

  scope "/feeds", BrightWeb do
    get("/vods.xml", RssController, :vods)
  end

  # Other scopes may use custom stacks.
  scope "/api", BrightWeb do
    pipe_through(:api)
    resources("/urls", UrlController, except: [:new, :edit])
    get("/health", PageController, :health)
  end

  redirect("/upload", "/uploads/new", :permanent, preserve_query_string: true)

  # Enable LiveDashboard and Swoosh mailbox preview in development
  if Application.compile_env(:bright, :dev_routes) do
    # If you want to use the LiveDashboard in production, you should put
    # it behind authentication and allow only admins to access it.
    # If your application does not have an admins-only section yet,
    # you can use Plug.BasicAuth to set up some basic authentication
    # as long as you are also using SSL (which you should anyway).
    import Phoenix.LiveDashboard.Router

    scope "/dev" do
      pipe_through(:browser)

      live_dashboard("/dashboard", metrics: BrightWeb.Telemetry)
    end
  end
end