from allauth.account import views as allauth_account_views
from allauth.mfa.base import views as allauth_mfa_views
from allauth.socialaccount import views as allauth_social_account_views
from allauth.urls import build_provider_urlpatterns
from django.conf import settings
from django.conf.urls import include
from django.contrib import admin
from django.contrib.auth.decorators import login_required
from django.urls import path
from django.urls import re_path
from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic import RedirectView
from drf_spectacular.views import SpectacularAPIView
from drf_spectacular.views import SpectacularSwaggerView
from rest_framework.routers import DefaultRouter

from documents.views import BulkDownloadView
from documents.views import BulkEditObjectsView
from documents.views import BulkEditView
from documents.views import ChatStreamingView
from documents.views import CorrespondentViewSet
from documents.views import CustomFieldViewSet
from documents.views import DeleteDocumentsView
from documents.views import DocumentTypeViewSet
from documents.views import EditPdfDocumentsView
from documents.views import GlobalSearchView
from documents.views import IndexView
from documents.views import LogViewSet
from documents.views import MergeDocumentsView
from documents.views import PostDocumentView
from documents.views import RemoteVersionView
from documents.views import RemovePasswordDocumentsView
from documents.views import ReprocessDocumentsView
from documents.views import RotateDocumentsView
from documents.views import SavedViewViewSet
from documents.views import SearchAutoCompleteView
from documents.views import SelectionDataView
from documents.views import SharedLinkView
from documents.views import ShareLinkBundleViewSet
from documents.views import ShareLinkViewSet
from documents.views import StatisticsView
from documents.views import StoragePathViewSet
from documents.views import SystemStatusView
from documents.views import TagViewSet
from documents.views import TasksViewSet
from documents.views import TrashView
from documents.views import UiSettingsView
from documents.views import UnifiedSearchViewSet
from documents.views import WorkflowActionViewSet
from documents.views import WorkflowTriggerViewSet
from documents.views import WorkflowViewSet
from documents.views import serve_logo
from paperless.consumers import StatusConsumer
from paperless.views import ApplicationConfigurationViewSet
from paperless.views import DisconnectSocialAccountView
from paperless.views import FaviconView
from paperless.views import GenerateAuthTokenView
from paperless.views import GroupViewSet
from paperless.views import PaperlessObtainAuthTokenView
from paperless.views import ProfileView
from paperless.views import SocialAccountProvidersView
from paperless.views import TOTPView
from paperless.views import UserViewSet
from paperless_mail.views import MailAccountViewSet
from paperless_mail.views import MailRuleViewSet
from paperless_mail.views import OauthCallbackView
from paperless_mail.views import ProcessedMailViewSet

api_router = DefaultRouter()
api_router.register(r"correspondents", CorrespondentViewSet)
api_router.register(r"document_types", DocumentTypeViewSet)
api_router.register(r"documents", UnifiedSearchViewSet)
api_router.register(r"logs", LogViewSet, basename="logs")
api_router.register(r"tags", TagViewSet)
api_router.register(r"saved_views", SavedViewViewSet)
api_router.register(r"storage_paths", StoragePathViewSet)
api_router.register(r"tasks", TasksViewSet, basename="tasks")
api_router.register(r"users", UserViewSet, basename="users")
api_router.register(r"groups", GroupViewSet, basename="groups")
api_router.register(r"mail_accounts", MailAccountViewSet)
api_router.register(r"mail_rules", MailRuleViewSet)
api_router.register(r"share_link_bundles", ShareLinkBundleViewSet)
api_router.register(r"share_links", ShareLinkViewSet)
api_router.register(r"workflow_triggers", WorkflowTriggerViewSet)
api_router.register(r"workflow_actions", WorkflowActionViewSet)
api_router.register(r"workflows", WorkflowViewSet)
api_router.register(r"custom_fields", CustomFieldViewSet)
api_router.register(r"config", ApplicationConfigurationViewSet)
api_router.register(r"processed_mail", ProcessedMailViewSet)


urlpatterns = [
    re_path(
        r"^api/",
        include(
            [
                re_path(
                    "^auth/",
                    include(
                        ("rest_framework.urls", "rest_framework"),
                        namespace="rest_framework",
                    ),
                ),
                re_path(
                    "^search/",
                    include(
                        [
                            re_path(
                                "^$",
                                GlobalSearchView.as_view(),
                                name="global_search",
                            ),
                            re_path(
                                "^autocomplete/",
                                SearchAutoCompleteView.as_view(),
                                name="autocomplete",
                            ),
                        ],
                    ),
                ),
                re_path(
                    "^statistics/",
                    StatisticsView.as_view(),
                    name="statistics",
                ),
                re_path(
                    "^documents/",
                    include(
                        [
                            re_path(
                                "^post_document/",
                                PostDocumentView.as_view(),
                                name="post_document",
                            ),
                            re_path(
                                "^bulk_edit/",
                                BulkEditView.as_view(),
                                name="bulk_edit",
                            ),
                            re_path(
                                "^delete/",
                                DeleteDocumentsView.as_view(),
                                name="delete_documents",
                            ),
                            re_path(
                                "^reprocess/",
                                ReprocessDocumentsView.as_view(),
                                name="reprocess_documents",
                            ),
                            re_path(
                                "^rotate/",
                                RotateDocumentsView.as_view(),
                                name="rotate_documents",
                            ),
                            re_path(
                                "^merge/",
                                MergeDocumentsView.as_view(),
                                name="merge_documents",
                            ),
                            re_path(
                                "^edit_pdf/",
                                EditPdfDocumentsView.as_view(),
                                name="edit_pdf_documents",
                            ),
                            re_path(
                                "^remove_password/",
                                RemovePasswordDocumentsView.as_view(),
                                name="remove_password_documents",
                            ),
                            re_path(
                                "^bulk_download/",
                                BulkDownloadView.as_view(),
                                name="bulk_download",
                            ),
                            re_path(
                                "^selection_data/",
                                SelectionDataView.as_view(),
                                name="selection_data",
                            ),
                            re_path(
                                "^chat/",
                                ChatStreamingView.as_view(),
                                name="chat_streaming_view",
                            ),
                        ],
                    ),
                ),
                re_path(
                    "^bulk_edit_objects/",
                    BulkEditObjectsView.as_view(),
                    name="bulk_edit_objects",
                ),
                re_path(
                    "^remote_version/",
                    RemoteVersionView.as_view(),
                    name="remoteversion",
                ),
                re_path(
                    "^ui_settings/",
                    UiSettingsView.as_view(),
                    name="ui_settings",
                ),
                path(
                    "token/",
                    PaperlessObtainAuthTokenView.as_view(),
                ),
                re_path(
                    "^profile/",
                    include(
                        [
                            re_path(
                                "^$",
                                ProfileView.as_view(),
                                name="profile_view",
                            ),
                            path(
                                "generate_auth_token/",
                                GenerateAuthTokenView.as_view(),
                            ),
                            path(
                                "disconnect_social_account/",
                                DisconnectSocialAccountView.as_view(),
                            ),
                            path(
                                "social_account_providers/",
                                SocialAccountProvidersView.as_view(),
                            ),
                            path(
                                "totp/",
                                TOTPView.as_view(),
                                name="totp_view",
                            ),
                        ],
                    ),
                ),
                re_path(
                    "^status/",
                    SystemStatusView.as_view(),
                    name="system_status",
                ),
                re_path(
                    "^trash/",
                    TrashView.as_view(),
                    name="trash",
                ),
                re_path(
                    r"^oauth/callback/",
                    OauthCallbackView.as_view(),
                    name="oauth_callback",
                ),
                re_path(
                    "^schema/",
                    include(
                        [
                            re_path(
                                "^$",
                                SpectacularAPIView.as_view(),
                                name="schema",
                            ),
                            re_path(
                                "^view/",
                                SpectacularSwaggerView.as_view(),
                                name="swagger-ui",
                            ),
                        ],
                    ),
                ),
                re_path("^auth/headless/", include("allauth.headless.urls")),
                re_path(
                    "^$",  # Redirect to the API swagger view
                    RedirectView.as_view(url="schema/view/"),
                ),
                *api_router.urls,
            ],
        ),
    ),
    re_path(r"share/(?P<slug>\w+)/?$", SharedLinkView.as_view()),
    re_path(r"^favicon.ico$", FaviconView.as_view(), name="favicon"),
    re_path(r"admin/", admin.site.urls),
    re_path(
        r"^fetch/",
        include(
            [
                re_path(
                    r"^doc/(?P<pk>\d+)$",
                    RedirectView.as_view(
                        url=settings.BASE_URL + "api/documents/%(pk)s/download/",
                    ),
                ),
                re_path(
                    r"^thumb/(?P<pk>\d+)$",
                    RedirectView.as_view(
                        url=settings.BASE_URL + "api/documents/%(pk)s/thumb/",
                    ),
                ),
                re_path(
                    r"^preview/(?P<pk>\d+)$",
                    RedirectView.as_view(
                        url=settings.BASE_URL + "api/documents/%(pk)s/preview/",
                    ),
                ),
            ],
        ),
    ),
    # Frontend assets TODO: this is pretty bad, but it works.
    path(
        "assets/<path:path>",
        RedirectView.as_view(
            url=settings.STATIC_URL + "frontend/en-US/assets/%(path)s",
        ),
        # TODO: with localization, this is even worse! :/
    ),
    # App logo
    re_path(r"^logo(?:/(?P<filename>.+))?/?$", serve_logo, name="app_logo"),
    # allauth
    path(
        "accounts/",
        include(
            [
                # see allauth/account/urls.py
                # login, logout, signup, account_inactive
                path("login/", allauth_account_views.login, name="account_login"),
                path("logout/", allauth_account_views.logout, name="account_logout"),
                path("signup/", allauth_account_views.signup, name="account_signup"),
                path(
                    "account_inactive/",
                    allauth_account_views.account_inactive,
                    name="account_inactive",
                ),
                # password reset
                path(
                    "password/",
                    include(
                        [
                            path(
                                "reset/",
                                allauth_account_views.password_reset,
                                name="account_reset_password",
                            ),
                            path(
                                "reset/done/",
                                allauth_account_views.password_reset_done,
                                name="account_reset_password_done",
                            ),
                            path(
                                "reset/key/done/",
                                allauth_account_views.password_reset_from_key_done,
                                name="account_reset_password_from_key_done",
                            ),
                        ],
                    ),
                ),
                re_path(
                    r"^confirm-email/(?P<key>[-:\w]+)/$",
                    allauth_account_views.ConfirmEmailView.as_view(),
                    name="account_confirm_email",
                ),
                re_path(
                    r"^password/reset/key/(?P<uidb36>[0-9A-Za-z]+)-(?P<key>.+)/$",
                    allauth_account_views.password_reset_from_key,
                    name="account_reset_password_from_key",
                ),
                # social account base urls, see allauth/socialaccount/urls.py
                path(
                    "3rdparty/",
                    include(
                        [
                            path(
                                "login/cancelled/",
                                allauth_social_account_views.login_cancelled,
                                name="socialaccount_login_cancelled",
                            ),
                            path(
                                "login/error/",
                                allauth_social_account_views.login_error,
                                name="socialaccount_login_error",
                            ),
                            path(
                                "signup/",
                                allauth_social_account_views.signup,
                                name="socialaccount_signup",
                            ),
                        ],
                    ),
                ),
                *build_provider_urlpatterns(),
                # mfa, see allauth/mfa/base/urls.py
                path(
                    "2fa/authenticate/",
                    allauth_mfa_views.authenticate,
                    name="mfa_authenticate",
                ),
            ],
        ),
    ),
    # Root of the Frontend
    re_path(
        r".*",
        login_required(ensure_csrf_cookie(IndexView.as_view())),
        name="base",
    ),
]


websocket_urlpatterns = [
    path("ws/status/", StatusConsumer.as_asgi()),
]

# Text in each page's <h1> (and above login form).
admin.site.site_header = "Paperless-ngx"
# Text at the end of each page's <title>.
admin.site.site_title = "Paperless-ngx"
# Text at the top of the admin index page.
admin.site.index_title = _("Paperless-ngx administration")
