import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const PUBLIC_PREFIXES = [
  '/login',
  '/api/auth',
  '/api/health',
  '/api/trpc/stellen.listPublic',
  '/api/setup',
  '/registrierung',
  '/impressum',
  '/datenschutz',
]
const PUBLIC_EXACT_PATHS = ['/']
const TENANT_SHARED_PATHS = ['/login', '/api', '/superadmin', '/registrierung', '/impressum', '/datenschutz', '/passwort-aendern']

// Reserved subdomains that shouldn't be treated as tenant slugs
const RESERVED_SUBDOMAINS = [
  'www', 'app', 'admin', 'localhost', 'superadmin', 'api',
  'logo.png', 'favicon.ico', 'robots.txt', 'sitemap.xml',
  'apple-touch-icon', 'android-chrome', 'manifest'
]

export function middleware(request: NextRequest) {
  const url = request.nextUrl
  const pathname = url.pathname

  // 1. Subdomain Extraction
  const hostname = request.headers.get('host') || ''
  const domainParts = hostname.split(':')[0].split('.')
  let slug = null

  // For localhost: tischler.localhost -> parts: ['tischler', 'localhost']
  // For production: tischler.innungsapp.de -> parts: ['tischler', 'innungsapp', 'de']
  if (
    domainParts.length > 2 ||
    (domainParts.length === 2 && domainParts[1] === 'localhost')
  ) {
    const potentialSlug = domainParts[0]
    if (!RESERVED_SUBDOMAINS.includes(potentialSlug)) {
      slug = potentialSlug
    }
  }

  // Normalize stale tenant-prefixed shared paths like /test/login to /login
  // before auth checks, otherwise callbackUrl can get stuck on /test/login.
  if (slug) {
    for (const sharedPath of TENANT_SHARED_PATHS) {
      const prefixedPath = `/${slug}${sharedPath}`
      if (pathname === prefixedPath || pathname.startsWith(`${prefixedPath}/`)) {
        const canonicalUrl = request.nextUrl.clone()
        canonicalUrl.pathname = pathname.replace(prefixedPath, sharedPath)
        return NextResponse.redirect(canonicalUrl)
      }
    }
  }

  // Allow static files from /public
  const isStaticFile = pathname.includes('.') && !pathname.startsWith('/api')
  const isPublic =
    isStaticFile ||
    PUBLIC_EXACT_PATHS.includes(pathname) ||
    PUBLIC_PREFIXES.some((p) => pathname.startsWith(p))

  // 2. Auth Check
  const sessionToken =
    request.cookies.get('better-auth.session_token') ??
    request.cookies.get('__Secure-better-auth.session_token')

  if (!isPublic && !sessionToken) {
    const loginUrl = new URL('/login', request.url)
    loginUrl.searchParams.set('callbackUrl', pathname)
    return NextResponse.redirect(loginUrl)
  }

  // 3. Subdomain Redirection / Rewrite
  if (slug) {
    // Paths that should not be rewritten into the slug folder
    // because they are shared across the entire app
    const isSharedPath = TENANT_SHARED_PATHS.some((p) => pathname.startsWith(p)) ||
                         pathname.startsWith('/_next') ||
                         /\.(png|jpg|jpeg|gif|svg|webp|ico|txt|xml)$/i.test(pathname)

    if (!isSharedPath && !pathname.startsWith(`/${slug}`)) {
      const rewriteUrl = request.nextUrl.clone()
      rewriteUrl.pathname = `/${slug}${pathname === '/' ? '' : pathname}`
      return NextResponse.rewrite(rewriteUrl)
    }
  } else {
    // Check if the user is trying to access a path that starts with a potential slug
    // but they are on the root domain.
    // Example: localhost/tischler/... should redirect to tischler.localhost/...
    const pathParts = pathname.split('/')
    if (pathParts.length > 1) {
      const potentialSlug = pathParts[1]
      // Check if it's a known non-reserved path but could be an organization slug
      // We don't want to redirect /login, /api, etc.
      const SHARED_PATHS = ['login', 'api', 'superadmin', 'dashboard', 'registrierung', 'impressum', 'datenschutz', '_next', 'uploads', 'favicon.ico', 'passwort-aendern']
      const isStaticAsset = /\.(png|jpg|jpeg|gif|svg|webp|ico|txt|xml)$/i.test(potentialSlug)
      const isValidSlug = /^[a-z0-9][a-z0-9-]*$/.test(potentialSlug)
      if (potentialSlug && !SHARED_PATHS.includes(potentialSlug) && !isStaticAsset && isValidSlug) {
        // This looks like a tenant path being accessed from the root domain.
        // Redirect to subdomain.
        const baseHost = hostname.split('.').slice(-2).join('.') // Simplistic, assumes domain.tld or localhost
        // For localhost it's special
        const isLocalhost = hostname.includes('localhost')
        const newHost = isLocalhost
          ? `${potentialSlug}.localhost${hostname.includes(':') ? `:${hostname.split(':')[1]}` : ''}`
          : `${potentialSlug}.${baseHost}`

        const remainingPath = '/' + pathParts.slice(2).join('/')
        return NextResponse.redirect(new URL(remainingPath, `${url.protocol}//${newHost}`))
      }
    }
  }

  return NextResponse.next()
}

export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico|uploads).*)',
  ],
}
