"""
Main URL configuration.
"""
import config.admin_site  # noqa: F401 — swaps admin.site to PanelAdminSite
from django.contrib import admin
from django.urls import path, include, re_path
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic import RedirectView
from apps.auction.views import domain_landing
from apps.brands.views import brand_detail
from apps.tenants import renewal_views

urlpatterns = [
    # Branded admin dashboard (PanelAdminSite)
    path('admin/', admin.site.urls),

    # A home screen shortcut saved from the old static site opens /index.html,
    # and iOS keeps that address in its cached manifest for the life of the
    # icon. Sending it to the homepage means those shortcuts keep working
    # instead of landing on a 404.
    path('index.html', RedirectView.as_view(url='/', permanent=True)),

    # Redirect legacy /shop/ → /products/
    path('shop/', RedirectView.as_view(url='/products/', permanent=True)),
    re_path(r'^shop/(?P<path>.*)$', RedirectView.as_view(url='/products/', permanent=True)),

    # Redirect malformed /service/<slug> → /startup/ for startup, else /services/<slug>/
    re_path(r'^service/(?P<slug>[\w-]+)/?$', RedirectView.as_view(url='/startup/', permanent=True)),

    # Public site
    path('', include('apps.pages.urls')),
    path('portfolio/', include('apps.portfolio.urls')),
    path('insights/', include('apps.insights.urls')),
    # Premium domains are served from the shop's Product model, which is where
    # the listings and all the money handling live. apps.auction stays
    # installed but unrouted: it is the older duplicate implementation.
    #
    # The address is /domains/, not /auction/. A premium name is sold at a
    # fixed price or by enquiry as often as by bidding, so "auction" described
    # one case out of three, and /products/ made a domain read as a shop item.
    # Note this does not collide with the registration search, which lives at
    # /products/domains/ inside the shop.
    path('domains/', include('apps.ecommerce.auction_urls')),

    # The old address, kept permanently. Links to listings get pasted into
    # emails and messages and outlive any rename, so /auction/<slug>/ has to
    # keep arriving somewhere sensible rather than 404ing.
    path('auction/', RedirectView.as_view(url='/domains/', permanent=True)),
    re_path(r'^auction/(?P<path>.*)$',
            RedirectView.as_view(url='/domains/%(path)s', permanent=True)),
    path('marketplace/', include('apps.marketplace.urls')),
    path('contact/', include('apps.contact.urls')),
    path('faq/', include('apps.faq.urls')),
    path('products/', include('apps.ecommerce.urls')),

    # Auth (FAB Club OAuth + local login)
    path('auth/', include('apps.accounts.urls')),
    path('social/', include('social_django.urls', namespace='social')),

    # FAB Club integration — /fab/login/, /fab/status/, /fab/disconnect/
    path('', include('apps.fab_auth.urls')),

    # CMS Dashboard
    path('cms/', include('apps.accounts.cms_urls')),

    # Media Hub — streaming endpoints + public player
    path('stream/', include('apps.media.urls')),
    path('watch/', include('apps.media.public_urls')),

    # Deal agreements (public — client-facing)
    path('deal/', include('apps.ecommerce.deal_urls')),
    path('quote/', include('apps.sales.quote_urls')),
    path('my-account/', include('apps.ecommerce.portal_urls')),

    # AI Chat widget API (called by embedded JS widget on any tenant site)
    path('chat/', include('apps.chat.urls', namespace='chat')),

    # CKEditor 5 file uploads
    path('ckeditor5/', include('django_ckeditor_5.urls')),

    # Fleet control endpoint used by tenant installs
    path('api/ftlink/', include('apps.ftlink.urls')),

    # Renewal payment links. Public and unauthenticated by design: the client
    # arrives from an email months after it was sent and must not need an
    # account to settle an invoice. The token is the whole of the security.
    path('renew/<str:token>/',        renewal_views.renew_invoice,  name='renew_invoice'),
    path('renew/<str:token>/pay/',    renewal_views.renew_checkout, name='renew_checkout'),
    path('renew/<str:token>/done/',   renewal_views.renew_return,   name='renew_return'),

]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
else:
    # Uploaded files need someone to serve them in production, and on these
    # installs nobody does. WhiteNoise handles STATIC_URL only. The vhost
    # proxies every path to gunicorn, so an Apache Alias for /media/ is not
    # reliably reached on a cPanel box, where the handler chain gets there
    # first. Django is behind the proxy that already works, so it answers.
    #
    # django.views.static.serve is not built for heavy traffic. These are
    # brochure sites serving their own logos and photographs, and the
    # alternative was every client image 404ing on their own site with
    # nothing in any log to explain it.
    from django.views.static import serve as _serve

    urlpatterns += [
        re_path(r'^media/(?P<path>.*)$', _serve, {'document_root': settings.MEDIA_ROOT}),
    ]

# The brand catch-all and the domain-for-sale page go on the very end, after
# the media route above.
#
# Order matters here and it is not obvious: the media route is appended to
# urlpatterns rather than declared inside it, so anything declared inside the
# list is tried first. A top-level <slug:slug>/ would therefore be reached
# before /media/, and a brand called "media" would shadow uploaded files.
# Putting these two last removes that whole class of collision.
urlpatterns += [
    path('brands/', include('apps.brands.urls')),
    path('<slug:slug>/', brand_detail, name='brand_detail'),

    # Domain-for-sale landing page — catch-all for domains pointed at this
    # server. Must be last so it doesn't swallow other routes.
    path('', domain_landing, name='domain_landing'),
]
