import 'server-only'
import { createAdminClient } from '@/lib/supabase/admin'
import { ensureBrokerPage } from '@/app/(auth)/actions'
import { getVisibleTrips, getTripCompletions } from '@/lib/data/trips'
import { loadDriverTripData, loadDriverChat, loadPilotAccess } from '@/lib/data/driver'
import { getRouteCreditBalance } from '@/lib/data/credits'
import { listContacts } from '@/lib/data/contacts'
import { getCompanyContext } from '@/lib/data/companies'
import { companyRoleLabel } from '@/lib/domain/company'
import { isActiveStatus, resolveStatusForUser, type TripCompletion } from '@/lib/domain/status'
import type { SessionUser } from '@/lib/auth'
import { contextForAccount } from '@/lib/page-context'
import type { BrokerPage, Trip, TripWarning } from '@/types/db'
import type { PermitLite, TripDriver } from '@/lib/data/dashboard-data'

/**
 * Dashboard data loaders, one per role page (article "Role-Specific Page
 * Separation", 2026-09-13). Extracted unchanged from the former single
 * /dashboard route so each role route loads only what its dashboard uses.
 */

export interface DashboardBase {
  trips: Trip[]
  warnings: TripWarning[]
  permits: PermitLite[]
  drivers: TripDriver[]
  completions: Record<string, TripCompletion>
}

/** Trips, warnings, per-trip permits and drivers, personal completion — used by every role dashboard. */
export async function loadDashboardBase(user: SessionUser): Promise<DashboardBase> {
  const admin = createAdminClient()
  const { trips, warnings } = await getVisibleTrips(user)
  const ids = trips.map((t) => t.id)
  let permits: PermitLite[] = []
  let drivers: TripDriver[] = []
  if (ids.length > 0) {
    const [permitsRes, driversRes] = await Promise.all([
      admin
        .from('permits')
        .select('id, trip_id, document_id, state_code, permit_number, effective_date, expiration_date')
        .in('trip_id', ids)
        .order('created_at'),
      admin
        .from('trip_participants')
        .select('trip_id, name, email')
        .in('trip_id', ids)
        .eq('role', 'driver')
        .neq('status', 'removed'),
    ])
    permits = (permitsRes.data ?? []) as PermitLite[]
    drivers = (driversRes.data ?? []) as TripDriver[]
  }
  // Personal completion state — every dashboard renders the status THIS user
  // sees, not a single trip-wide one (2026-09-07).
  const completions = await getTripCompletions(user, ids)
  return { trips, warnings, permits, drivers, completions }
}

/**
 * Self-heal: brokers always have an intake page. Decided by PAGE CONTEXT, not
 * the raw account role — an admin lands on the freight broker pages and needs
 * the same intake page for "New Trip Request" (regression 2026-09-13: the
 * admin account fell through to the generic form).
 */
export async function loadBrokerPage(user: SessionUser): Promise<BrokerPage | null> {
  // Internal testers may reach the freight broker pages while their session is
  // another test account (the pilot testing bar's Broker button is a link,
  // not a session switch, since no broker test login exists). They still get
  // an intake page, so Copy Intake Link and New Trip Request keep working
  // (regression 2026-09-13).
  if (contextForAccount(user.role) !== 'broker' && !user.internal) return null
  const admin = createAdminClient()
  const { data } = await admin.from('broker_pages').select('*').eq('owner_id', user.id).maybeSingle()
  if (data) return data as BrokerPage
  await ensureBrokerPage(user.id, user.company || user.name)
  const { data: created } = await admin.from('broker_pages').select('*').eq('owner_id', user.id).maybeSingle()
  return (created as BrokerPage | null) ?? null
}

export type CompanyStatus = { label: string; href: string; tone: 'ok' | 'pending' | 'none' } | null

/** Company verification chip (Task 89) — broker and carrier accounts only. */
export async function loadCompanyStatus(user: SessionUser): Promise<CompanyStatus> {
  if (user.role !== 'broker' && user.role !== 'dispatcher') return null
  const ctx = await getCompanyContext(user.id)
  if (!ctx.available) return null
  if (ctx.membership?.status === 'approved' && ctx.company) {
    return {
      label: `Approved company agent · ${ctx.company.display_name} · ${companyRoleLabel(ctx.membership.role, ctx.company.company_type)}`,
      href: '/company',
      tone: 'ok',
    }
  }
  if (ctx.claim && ['pending_corporate_approval', 'company_verification_pending', 'admin_review_required'].includes(ctx.claim.claim_status)) {
    return { label: 'Company approval pending', href: '/settings', tone: 'pending' }
  }
  return { label: 'Company: not connected · Verify your company access', href: '/settings', tone: 'none' }
}

/** Saved drivers and brokers for the carrier dashboard's Drivers tab (Task 98). */
export async function loadCarrierContacts(user: SessionUser) {
  return listContacts(user.id)
}

/**
 * Carrier driver dashboard extras: permit file links, route requests in all
 * three delivery formats, unit profiles, the focused trip's chat, credits,
 * and each pilot's access for the state cards.
 */
export async function loadDriverDashboard(user: SessionUser, base: DashboardBase) {
  const ids = base.trips.map((t) => t.id)
  const { routeRequests, units, permitUrls } = await loadDriverTripData(ids, base.permits)
  // Must match the driver view's own focus rule exactly — its first active
  // trip, judged by the status THIS user sees.
  const focusedTripId =
    base.trips.find((t) => isActiveStatus(resolveStatusForUser(t.status, base.completions[t.id])))?.id ?? null
  const [routeCredits, chatBundle, pilotAccess] = await Promise.all([
    getRouteCreditBalance(user),
    loadDriverChat(focusedTripId, user),
    loadPilotAccess(focusedTripId),
  ])
  return { routeRequests, units, permitUrls, routeCredits, ...chatBundle, pilotAccess }
}
