/**
 * Access Control Type Definitions
 *
 * Core interfaces for subscription-based access control, feature gating,
 * and subscription health monitoring.
 *
 * @module types/access-control
 */

/**
 * Subscription statuses as stored in the database
 */
export type SubscriptionStatus =
  | 'active'
  | 'trialing'
  | 'past_due'
  | 'suspended'
  | 'cancelled'
  | 'incomplete'
  | 'incomplete_expired'
  | 'paused'
  | 'unpaid';

/**
 * User access levels based on subscription status
 */
export type AccessLevel =
  | 'full' // Active subscription with full access
  | 'trial' // During trial period
  | 'limited' // Past due or at risk - limited functionality
  | 'read_only' // Suspended - can view data but not modify
  | 'none'; // No access - cancelled or expired

/**
 * Features that can be access-controlled
 */
export type Feature =
  | 'dashboard' // Main dashboard access
  | 'appointments' // Appointment management
  | 'whatsapp' // WhatsApp messaging
  | 'analytics' // Analytics and reporting
  | 'team_management' // Team/staff management
  | 'billing' // Billing and subscription management (always accessible)
  | 'settings' // Account settings
  | 'knowledge_base' // Knowledge base access
  | 'notifications' // Notification preferences
  | 'export_data' // Data export functionality
  | 'api_access'; // API access

/**
 * Result of checking user access
 */
export interface UserAccessResult {
  /** Whether user has any access */
  hasAccess: boolean;
  /** The level of access granted */
  accessLevel: AccessLevel;
  /** Current subscription status */
  subscriptionStatus: SubscriptionStatus | null;
  /** Whether subscription is in trial */
  isTrialing: boolean;
  /** Trial end date if applicable */
  trialEndsAt: Date | null;
  /** Days remaining in trial */
  trialDaysRemaining: number | null;
  /** Whether subscription is at risk (payment issues) */
  isAtRisk: boolean;
  /** Number of failed payment attempts */
  paymentFailureCount: number;
  /** Whether a valid payment method exists */
  hasPaymentMethod: boolean;
  /** When current period ends */
  currentPeriodEnd: Date | null;
  /** Whether subscription will cancel at period end */
  cancelAtPeriodEnd: boolean;
  /** Reason for restricted access if applicable */
  restrictionReason?: string;
  /** Suggested action for the user */
  suggestedAction?: string;
  /** URL for the suggested action */
  actionUrl?: string;
}

/**
 * Result of checking if a subscription is at risk
 */
export interface SubscriptionRiskResult {
  /** Whether subscription is at risk */
  isAtRisk: boolean;
  /** Risk level from 0 (none) to 3 (critical) */
  riskLevel: 0 | 1 | 2 | 3;
  /** Risk factors identified */
  riskFactors: RiskFactor[];
  /** Recommended actions to mitigate risk */
  recommendations: string[];
}

/**
 * Individual risk factors for a subscription
 */
export interface RiskFactor {
  /** Type of risk */
  type:
    | 'payment_failed'
    | 'no_payment_method'
    | 'trial_ending'
    | 'past_due'
    | 'cancellation_pending'
    | 'multiple_failures';
  /** Severity: low, medium, high, critical */
  severity: 'low' | 'medium' | 'high' | 'critical';
  /** Human-readable description */
  description: string;
  /** When this risk was first detected */
  detectedAt?: Date;
  /** Additional context */
  metadata?: Record<string, unknown>;
}

/**
 * Result of checking feature access
 */
export interface FeatureAccessResult {
  /** Whether user can access the feature */
  canAccess: boolean;
  /** Access level for the feature */
  accessLevel: AccessLevel;
  /** Reason if access is denied */
  reason?: string;
  /** Whether feature is in read-only mode */
  readOnly: boolean;
  /** Suggested upgrade path if applicable */
  upgradeRequired?: boolean;
  /** Message to show user */
  message?: string;
}

/**
 * Options for access control checks
 */
export interface AccessCheckOptions {
  /** Whether to include organization membership in check */
  includeOrgMembership?: boolean;
  /** Whether to bypass cache */
  bypassCache?: boolean;
  /** Whether to check specific feature */
  feature?: Feature;
}

/**
 * Subscription data needed for access control
 */
export interface SubscriptionForAccess {
  id: string;
  status: string;
  tierId: string;
  trialEndsAt: Date | null;
  currentPeriodEnd: Date;
  cancelAtPeriodEnd: boolean;
  paymentFailureCount: number;
  paymentMethodId: string | null;
  lastPaymentAttempt: Date | null;
  lastPaymentDate: Date | null;
}

/**
 * User with subscription for access control
 */
export interface UserWithSubscription {
  id: string;
  email: string;
  name: string | null;
  subscription: SubscriptionForAccess | null;
  organizationMembership?: {
    organizationId: string;
    role: string;
    organization: {
      id: string;
      name: string;
      ownerId: string;
    };
  } | null;
}

/**
 * Constants for access control
 */
export const ACCESS_CONTROL_CONSTANTS = {
  /** Number of failed payments to consider at risk */
  AT_RISK_FAILURE_COUNT: 2,
  /** Days before trial end to consider "ending soon" */
  TRIAL_ENDING_SOON_DAYS: 3,
  /** Features always accessible regardless of subscription */
  ALWAYS_ACCESSIBLE_FEATURES: ['billing', 'settings'] as Feature[],
  /** Features accessible in read-only mode */
  READ_ONLY_FEATURES: ['dashboard', 'analytics', 'knowledge_base'] as Feature[],
  /** Grace period days after payment failure */
  PAYMENT_GRACE_PERIOD_DAYS: 7,
} as const;

/**
 * Map of access levels to allowed features
 */
export const ACCESS_LEVEL_FEATURES: Record<AccessLevel, Feature[]> = {
  full: [
    'dashboard',
    'appointments',
    'whatsapp',
    'analytics',
    'team_management',
    'billing',
    'settings',
    'knowledge_base',
    'notifications',
    'export_data',
    'api_access',
  ],
  trial: [
    'dashboard',
    'appointments',
    'whatsapp',
    'analytics',
    'team_management',
    'billing',
    'settings',
    'knowledge_base',
    'notifications',
    'export_data',
    'api_access',
  ],
  limited: [
    'dashboard',
    'appointments',
    'analytics',
    'billing',
    'settings',
    'knowledge_base',
    'notifications',
  ],
  read_only: ['dashboard', 'analytics', 'billing', 'settings', 'knowledge_base'],
  none: ['billing', 'settings'], // Always allow access to billing to fix subscription
};

/**
 * Messages for different restriction scenarios
 */
export const RESTRICTION_MESSAGES = {
  payment_failed: {
    message: 'Your payment could not be processed. Please update your payment method.',
    action: 'Update Payment Method',
    url: '/en/dashboard?tab=billing',
  },
  trial_expired: {
    message: 'Your free trial has ended. Subscribe to continue using Mawidi.',
    action: 'Subscribe Now',
    url: '/en/dashboard?tab=billing',
  },
  trial_ending: {
    message: 'Your free trial is ending soon. Add a payment method to continue.',
    action: 'Add Payment Method',
    url: '/en/dashboard?tab=billing',
  },
  suspended: {
    message: 'Your subscription has been suspended. Please resolve payment issues.',
    action: 'Resolve Now',
    url: '/en/dashboard?tab=billing',
  },
  cancelled: {
    message: 'Your subscription has been cancelled.',
    action: 'Reactivate',
    url: '/en/dashboard?tab=billing&action=reactivate',
  },
  no_subscription: {
    message: 'No active subscription found. Start your free trial today.',
    action: 'Start Free Trial',
    url: '/en/pricing',
  },
  no_payment_method: {
    message: 'No payment method on file. Add one before your trial ends.',
    action: 'Add Payment Method',
    url: '/en/dashboard?tab=billing',
  },
} as const;
