import {
  Entity,
  Column,
  ManyToOne,
  JoinColumn,
  Unique,
} from 'typeorm';
import { BaseEntity } from '../database/base.entity';
import { RoleEntity } from './role.entity';

/**
 * Access levels per module.
 * Per CLAUDE.md line 75: None / View / Create / Edit / Delete
 */
export enum AccessLevel {
  NONE = 'none',
  VIEW = 'view',
  CREATE = 'create',
  EDIT = 'edit',
  DELETE = 'delete',
}

/**
 * Module names matching Phase 1 scope.
 * Per scope doc: 14 modules in Phase 1.
 *
 * NOTE: This is NOT a hardcoded role check — it's a reference list
 * of modules that permissions are assigned against.
 */
/**
 * Module order mirrors the sidebar (AppLayout.tsx). Each sidebar sub-menu
 * maps to its own module row in the Roles → Permissions dialog, except
 * the Settings group which stays unified under one SETTINGS module.
 */
export enum ModuleName {
  // Queries
  QUERY = 'query',
  // Bookings group
  BOOKING = 'booking',
  DRIVER_ASSIGNMENT = 'driver_assignment',
  MOVEMENT_CHART = 'movement_chart',
  PAYMENT_SETTLEMENT = 'payment_settlement',
  // Pricing group
  TRANSPORT_PRICING = 'transport_pricing',
  ACTIVITY_PRICING = 'activity_pricing',
  // Services group
  HOTEL = 'hotel',
  TRANSPORTATION = 'transportation',
  ACTIVITY = 'activity',
  // Masters group
  SUPPLIER = 'supplier',
  DRIVER = 'driver',
  VEHICLE = 'vehicle',
  // Settings group (single module covers all 10 sidebar items including
  // Seasons, Destinations, Trip Sources, Users, Roles, etc.)
  SETTINGS = 'settings',
}

/**
 * RolePermission entity — maps Role × Module → AccessLevel.
 *
 * Per CLAUDE.md:
 * - All permission checks via DB/Redis only
 * - Access levels per module: None / View / Create / Edit / Delete
 * - Permissions cached in Redis → invalidate on any permission change
 */
@Entity('role_permissions')
@Unique(['role', 'module'])
export class RolePermissionEntity extends BaseEntity {
  @ManyToOne(() => RoleEntity, (role) => role.permissions, {
    onDelete: 'CASCADE',
  })
  @JoinColumn({ name: 'role_id' })
  role: RoleEntity;

  @Column({ type: 'varchar', length: 100 })
  module: string; // ModuleName value

  @Column({ type: 'enum', enum: AccessLevel, default: AccessLevel.NONE })
  access_level: AccessLevel;
}
