(ns ajet.chat.api.routes
  "Reitit router with all API endpoint groups.

   All routes organized by feature domain. Middleware pipeline applied
   in the order specified by the PRD."
  (:require [reitit.ring :as ring]
            [reitit.ring.middleware.parameters :as parameters]
            [reitit.ring.middleware.muuntaja :as muuntaja]
            [ajet.chat.api.middleware :as mw]
            [ajet.chat.shared.logging :as logging]
            [ajet.chat.api.handlers.communities :as communities]
            [ajet.chat.api.handlers.channels :as channels]
            [ajet.chat.api.handlers.categories :as categories]
            [ajet.chat.api.handlers.messages :as messages]
            [ajet.chat.api.handlers.reactions :as reactions]
            [ajet.chat.api.handlers.dms :as dms]
            [ajet.chat.api.handlers.users :as users]
            [ajet.chat.api.handlers.notifications :as notifications]
            [ajet.chat.api.handlers.presence :as presence]
            [ajet.chat.api.handlers.search :as search]
            [ajet.chat.api.handlers.invites :as invites]
            [ajet.chat.api.handlers.webhooks :as webhooks]
            [ajet.chat.api.handlers.commands :as commands]
            [ajet.chat.api.handlers.upload :as upload]
            [ajet.chat.api.handlers.health :as health]
            [ajet.chat.api.handlers.admin :as admin]))

(defn router
  "Build the reitit router with all API routes."
  []
  (ring/router
    [["/api"

      ;; Health check - no auth, no ban/mute check
      ["/health" {:get {:handler health/health-check}}]

      ;; Communities
      ["/communities"
       ["" {:get  {:handler communities/list-communities}
            :post {:handler communities/create-community}}]
       ["/:id" {:get    {:handler communities/get-community}
                :put    {:handler communities/update-community}
                :delete {:handler communities/delete-community}}]

       ;; Community-scoped channels
       ["/:cid/channels" {:get  {:handler channels/list-channels
                                  :middleware [mw/wrap-ban-check]}
                           :post {:handler channels/create-channel
                                  :middleware [mw/wrap-ban-check mw/wrap-mute-check]}}]

       ;; Community-scoped categories
       ["/:cid/categories" {:get  {:handler categories/list-categories
                                    :middleware [mw/wrap-ban-check]}
                             :post {:handler categories/create-category
                                    :middleware [mw/wrap-ban-check mw/wrap-mute-check]}}]

       ;; Community members
       ["/:cid/members"
        ["" {:get {:handler users/list-community-members
                   :middleware [mw/wrap-ban-check]}}]
        ["/:uid" {:put    {:handler users/update-community-member
                           :middleware [mw/wrap-ban-check]}
                  :delete {:handler users/kick-member
                           :middleware [mw/wrap-ban-check]}}]]

       ;; Presence
       ["/:cid/presence" {:get {:handler presence/get-presence
                                :middleware [mw/wrap-ban-check]}}]

       ;; Invites
       ["/:cid/invites"
        ["" {:post {:handler invites/create-invite
                    :middleware [mw/wrap-ban-check]}
             :get  {:handler invites/list-invites
                    :middleware [mw/wrap-ban-check]}}]
        ["/direct" {:post {:handler invites/direct-invite
                           :middleware [mw/wrap-ban-check]}}]]

       ;; Webhooks
       ["/:cid/webhooks" {:post {:handler webhooks/create-webhook
                                  :middleware [mw/wrap-ban-check]}
                           :get  {:handler webhooks/list-webhooks
                                  :middleware [mw/wrap-ban-check]}}]]

      ;; Channels (by channel ID)
      ["/channels/:id"
       ["" {:get    {:handler channels/get-channel}
            :put    {:handler channels/update-channel}
            :delete {:handler channels/delete-channel}}]
       ["/join" {:post {:handler channels/join-channel
                        :middleware [mw/wrap-ban-check]}}]
       ["/leave" {:post {:handler channels/leave-channel}}]
       ["/members" {:get {:handler channels/list-channel-members}}]
       ["/messages" {:get  {:handler messages/list-messages}
                     :post {:handler messages/send-message
                            :middleware [mw/wrap-mute-check]}}]
       ["/upload" {:post {:handler upload/upload-file}}]
       ["/read" {:post {:handler messages/mark-read}}]]

      ;; Categories (by category ID)
      ["/categories/:id" {:put    {:handler categories/update-category}
                          :delete {:handler categories/delete-category}}]

      ;; Messages (by message ID)
      ["/messages/:id"
       ["" {:get    {:handler messages/get-message}
            :put    {:handler messages/edit-message
                     :middleware [mw/wrap-mute-check]}
            :delete {:handler messages/delete-message}}]
       ["/thread" {:get {:handler messages/get-thread}}]
       ["/reactions"
        ["" {:get {:handler reactions/list-reactions}}]
        ["/:emoji" {:put    {:handler reactions/add-reaction
                             :middleware [mw/wrap-mute-check]}
                    :delete {:handler reactions/remove-reaction}}]]]

      ;; DMs
      ["/dms"
       ["" {:get  {:handler dms/list-dms}
            :post {:handler dms/create-dm}}]
       ["/group" {:post {:handler dms/create-group-dm}}]]

      ;; Users & Profile
      ["/me" {:get {:handler users/get-me}
              :put {:handler users/update-me}}]
      ["/users/:id" {:get {:handler users/get-user}}]

      ;; Notifications
      ["/notifications"
       ["" {:get {:handler notifications/list-notifications}}]
       ["/read" {:post {:handler notifications/mark-read}}]
       ["/unread-count" {:get {:handler notifications/unread-count}}]]

      ;; Presence & Heartbeat
      ["/heartbeat" {:post {:handler presence/heartbeat}}]

      ;; Search
      ["/search" {:get {:handler search/search-handler}}]

      ;; Invites (by invite ID / code)
      ["/invites/:id" {:delete {:handler invites/revoke-invite}}]
      ["/invites/:code/accept" {:post {:handler invites/accept-invite}}]

      ;; Webhooks (by webhook ID)
      ["/webhooks/:id"
       ["" {:delete {:handler webhooks/delete-webhook}}]
       ["/incoming" {:post {:handler webhooks/incoming-webhook}}]]

      ;; Slash commands
      ["/commands" {:post {:handler commands/execute-command}}]

      ;; Admin — OAuth provider management
      ["/admin/oauth-providers"
       ["" {:get  {:handler admin/list-providers}
            :post {:handler admin/create-provider}}]
       ["/:id" {:put    {:handler admin/update-provider}
                :delete {:handler admin/delete-provider}}]]]]

    {:data {:middleware [parameters/parameters-middleware]}}))

(defn app
  "Build the full Ring handler with middleware stack."
  [system]
  (let [handler (ring/ring-handler
                  (router)
                  ;; Default handler for unmatched routes
                  (ring/create-default-handler
                    {:not-found
                     (constantly (mw/error-response 404 "NOT_FOUND" "Route not found"))
                     :method-not-allowed
                     (constantly (mw/error-response 405 "METHOD_NOT_ALLOWED" "Method not allowed"))}))]
    (-> handler
        mw/wrap-user-context
        mw/wrap-json-body
        (mw/wrap-system system)
        logging/wrap-request-logging
        mw/wrap-exception-handler)))
