import type {
  Company, CompanyMembership, CompanyPermissionLevel, CompanyRole, CompanyVerificationSource, MembershipStatus,
} from '@/types/db'
import { canManageCompany } from '@/lib/domain/company'

/**
 * Carrier Dashboard → Company Info (Nash, 2026-09-19).
 *
 * "A HeavyHaul Agent user is not automatically the carrier company." Three
 * objects: the user, the carrier company, and the membership between them.
 * The membership carries two independent axes:
 *
 *   relationship  pending → "Waiting for Verification", approved → "Verified",
 *                 rejected, revoked            (company_memberships.status)
 *   permission    member | company_admin       (company_memberships.permission_level)
 *
 * A Carrier Company Admin is still a Carrier Dispatcher — same dashboard,
 * same role — with company-scoped management powers. HeavyHaul Agent admins
 * get the management view on any carrier for support, and every manual
 * action is audited.
 *
 * Pure rules; the data layer does the I/O.
 */

export type RelationshipStatus = 'pending' | 'verified' | 'rejected' | 'revoked'

/** Which Company Info screen the viewer gets. */
export type CompanyInfoView =
  /** No carrier connected yet — offer the MC request. */
  | 'none'
  /** STATE 1 — waiting for the company to verify the relationship. */
  | 'pending'
  /** STATE 2 — verified, read-only company information. */
  | 'verified'
  /** STATE 3 — Carrier Company Admin (or HeavyHaul admin) management view. */
  | 'company_admin'
  | 'rejected'
  | 'revoked'

export const RELATIONSHIP_LABELS: Record<RelationshipStatus, string> = {
  pending: 'Waiting for Verification',
  verified: 'Verified',
  rejected: 'Not Verified',
  revoked: 'Relationship Revoked',
}

export const PERMISSION_LABELS: Record<CompanyPermissionLevel, string> = {
  member: 'Member',
  company_admin: 'Company Admin',
}

/** Reasons a Company Admin can give when rejecting. Stored; the label is what the requester sees. */
export const REJECTION_REASONS = [
  { value: 'unknown_person', label: 'We do not recognize this person' },
  { value: 'no_longer_works', label: 'No longer works with company' },
  { value: 'wrong_carrier', label: 'Wrong carrier' },
  { value: 'other', label: 'Other' },
] as const
export type RejectionReason = (typeof REJECTION_REASONS)[number]['value']

export const VERIFICATION_SOURCES: { value: CompanyVerificationSource; label: string }[] = [
  { value: 'FMCSA', label: 'FMCSA' },
  { value: 'HIGHWAY', label: 'Highway' },
  { value: 'MANUAL_ADMIN', label: 'HeavyHaul Agent (manual)' },
  { value: 'OTHER_VERIFIED_SOURCE', label: 'Other verified source' },
]

export function relationshipStatus(status: MembershipStatus | null | undefined): RelationshipStatus | 'none' {
  switch (status) {
    case 'pending':
      return 'pending'
    case 'approved':
      return 'verified'
    case 'rejected':
      return 'rejected'
    case 'revoked':
      return 'revoked'
    default:
      return 'none'
  }
}

/**
 * Permission inside the company. Before migration 0021 there is no column,
 * so owner/admin roles imply company_admin — the rule 0013 already used.
 */
export function permissionLevel(m: Pick<CompanyMembership, 'role' | 'permission_level'> | null | undefined): CompanyPermissionLevel {
  if (!m) return 'member'
  if (m.permission_level) return m.permission_level
  return canManageCompany(m.role) ? 'company_admin' : 'member'
}

/**
 * Role as the carrier side reads it. On a carrier everyone who dispatches is
 * a Carrier Dispatcher — "Company Admin" is the PERMISSION, shown separately
 * (Nash: "Role: Carrier Dispatcher · Company Permission: Company Admin").
 */
export function carrierRoleLabel(role: CompanyRole): string {
  switch (role) {
    case 'company_owner':
      return 'Company Owner'
    case 'billing_admin':
      return 'Billing Admin'
    case 'viewer':
      return 'Viewer'
    default:
      return 'Carrier Dispatcher'
  }
}

export function companyInfoView(params: {
  membership: Pick<CompanyMembership, 'status' | 'role' | 'permission_level'> | null
  viewerIsPlatformAdmin: boolean
}): CompanyInfoView {
  if (params.viewerIsPlatformAdmin) return 'company_admin'
  const rel = relationshipStatus(params.membership?.status)
  if (rel === 'none') return 'none'
  if (rel === 'verified') return permissionLevel(params.membership) === 'company_admin' ? 'company_admin' : 'verified'
  return rel
}

/**
 * Backend gate for every management request (§25): the caller must be a
 * verified (approved, not revoked) member of THIS company with company_admin
 * permission — or a HeavyHaul Agent admin.
 */
export function canManageCarrierCompany(params: {
  membership: Pick<CompanyMembership, 'status' | 'role' | 'permission_level' | 'company_id'> | null
  companyId: string
  viewerIsPlatformAdmin: boolean
}): boolean {
  if (params.viewerIsPlatformAdmin) return true
  const m = params.membership
  if (!m || m.company_id !== params.companyId) return false
  if (m.status !== 'approved') return false
  return permissionLevel(m) === 'company_admin'
}

/** Valid relationship transitions. Nothing else is allowed, so a double click cannot re-approve a revoked person. */
export function membershipTransition(
  from: MembershipStatus,
  action: 'approve' | 'reject' | 'revoke' | 'reinstate',
): { ok: true; to: MembershipStatus } | { ok: false; error: string } {
  switch (action) {
    case 'approve':
      return from === 'pending' ? { ok: true, to: 'approved' } : { ok: false, error: 'Only a pending request can be approved.' }
    case 'reject':
      return from === 'pending' ? { ok: true, to: 'rejected' } : { ok: false, error: 'Only a pending request can be rejected.' }
    case 'revoke':
      return from === 'approved' ? { ok: true, to: 'revoked' } : { ok: false, error: 'Only a verified relationship can be revoked.' }
    case 'reinstate':
      // Nash, 2026-09-22: a rejected or revoked member can be let back in by the Company Admin.
      return from === 'rejected' || from === 'revoked' ? { ok: true, to: 'approved' } : { ok: false, error: 'Only a rejected or revoked relationship can be reinstated.' }
  }
}

/** Company-level badge shown in the Company Info header. */
export function carrierCompanyBadge(company: Pick<Company, 'verification_level' | 'verification_status'>): { label: string; tone: 'ok' | 'pending' | 'none' } {
  if (company.verification_level >= 2) return { label: 'Verified Carrier', tone: 'ok' }
  if (company.verification_level === 1) return { label: 'Public Data Matched', tone: 'pending' }
  return { label: 'Unverified Carrier', tone: 'none' }
}

/**
 * Official identity (from FMCSA / Highway / manual admin) vs the editable
 * HeavyHaul Agent profile. A Company Admin edits only the second list; the
 * first changes through a verification source or a HeavyHaul admin.
 */
export const OFFICIAL_COMPANY_FIELDS = [
  'legal_name', 'dba_name', 'mc_number', 'dot_number', 'physical_address', 'mailing_address',
  'corporate_phone', 'official_company_email',
] as const
export const EDITABLE_COMPANY_FIELDS = [
  'display_name', 'logo_url', 'operations_phone', 'operations_email', 'dispatch_contact', 'preferred_contact', 'description',
] as const
export type EditableCompanyField = (typeof EDITABLE_COMPANY_FIELDS)[number]

export function isEditableCompanyField(field: string): field is EditableCompanyField {
  return (EDITABLE_COMPANY_FIELDS as readonly string[]).includes(field)
}

/** "MC 123456 | USDOT 1234567" or what is known. */
export function mcDotLine(c: Pick<Company, 'mc_number' | 'dot_number'>): string {
  return [c.mc_number ? `MC ${c.mc_number}` : null, c.dot_number ? `USDOT ${c.dot_number}` : null].filter(Boolean).join(' | ')
}

/** Email events the relationship flow raises; each maps to an admin-managed template of the same key. */
export const COMPANY_EMAIL_EVENTS = [
  'company_relationship_requested',
  'company_relationship_approved',
  'company_relationship_rejected',
  'company_relationship_revoked',
  'company_verification_reminder',
] as const
export type CompanyEmailEvent = (typeof COMPANY_EMAIL_EVENTS)[number]

/** Audit event types written for every relationship / profile action (§27). */
export const COMPANY_AUDIT = {
  requested: 'dispatcher_relationship_requested',
  approved: 'dispatcher_approved',
  rejected: 'dispatcher_rejected',
  revoked: 'dispatcher_revoked',
  adminGranted: 'company_admin_permission_granted',
  adminRemoved: 'company_admin_permission_removed',
  profileChanged: 'company_profile_changed',
  officialEmailChanged: 'official_company_email_changed',
  sourceChanged: 'verification_source_changed',
  reminderSent: 'company_verification_reminder_sent',
  invited: 'dispatcher_invited',
  bulkInvited: 'dispatchers_bulk_invited',
  invitationClaimed: 'invitation_claimed',
  reinstated: 'dispatcher_reinstated',
  /** D15 (2026-09-30): a carrier member's title changed (Dispatcher ↔ Safety Manager …). */
  roleChanged: 'member_role_changed',
} as const

export const AUDIT_LABELS: Record<string, string> = {
  [COMPANY_AUDIT.requested]: 'Dispatcher relationship requested',
  [COMPANY_AUDIT.approved]: 'Dispatcher approved',
  [COMPANY_AUDIT.rejected]: 'Dispatcher rejected',
  [COMPANY_AUDIT.revoked]: 'Dispatcher revoked',
  [COMPANY_AUDIT.adminGranted]: 'Company Admin permission granted',
  [COMPANY_AUDIT.adminRemoved]: 'Company Admin permission removed',
  [COMPANY_AUDIT.profileChanged]: 'Company profile changed',
  [COMPANY_AUDIT.officialEmailChanged]: 'Official company email changed',
  [COMPANY_AUDIT.sourceChanged]: 'Verification source changed',
  [COMPANY_AUDIT.reminderSent]: 'Verification reminder sent',
  [COMPANY_AUDIT.invited]: 'Dispatcher invited by Company Admin',
  [COMPANY_AUDIT.bulkInvited]: 'Bulk invitation sent by Company Admin',
  [COMPANY_AUDIT.invitationClaimed]: 'Invitation claimed — verified on first sign-in',
  [COMPANY_AUDIT.reinstated]: 'Dispatcher reinstated by Company Admin',
  [COMPANY_AUDIT.roleChanged]: 'Member role changed by Company Admin',
  claim_created: 'Company access requested',
  claim_approved: 'Company access approved',
  claim_denied: 'Company access denied',
  claim_withdrawn: 'Request withdrawn',
  access_revoked: 'Access revoked',
  role_changed: 'Role changed',
  approval_resent: 'Approval request resent',
}
