import { UserRole } from "./middleware";

// 권한 타입 정의
export enum Permission {
  // 사용자 관리
  USER_CREATE = "user:create",
  USER_READ = "user:read",
  USER_UPDATE = "user:update",
  USER_DELETE = "user:delete",
  USER_MANAGE_ROLES = "user:manage_roles",

  // 사이트 관리
  SITE_CREATE = "site:create",
  SITE_READ = "site:read",
  SITE_UPDATE = "site:update",
  SITE_DELETE = "site:delete",
  SITE_PUBLISH = "site:publish",

  // 섹션/페이지 관리
  SECTION_CREATE = "section:create",
  SECTION_READ = "section:read",
  SECTION_UPDATE = "section:update",
  SECTION_DELETE = "section:delete",
  SECTION_PUBLISH = "section:publish",

  // 템플릿 관리
  TEMPLATE_CREATE = "template:create",
  TEMPLATE_READ = "template:read",
  TEMPLATE_UPDATE = "template:update",
  TEMPLATE_DELETE = "template:delete",
  TEMPLATE_PUBLISH = "template:publish",

  // 파일 관리
  FILE_UPLOAD = "file:upload",
  FILE_READ = "file:read",
  FILE_DELETE = "file:delete",

  // 시스템 관리
  SYSTEM_SETTINGS = "system:settings",
  SYSTEM_AUDIT = "system:audit",
  SYSTEM_BACKUP = "system:backup",

  // 테넌트 관리
  TENANT_CREATE = "tenant:create",
  TENANT_READ = "tenant:read",
  TENANT_UPDATE = "tenant:update",
  TENANT_DELETE = "tenant:delete",
}

// 역할별 권한 매핑
export const ROLE_PERMISSIONS: Record<UserRole, Permission[]> = {
  [UserRole.ADMIN]: [
    // 모든 권한
    ...Object.values(Permission),
  ],

  [UserRole.EDITOR]: [
    // 사용자 읽기
    Permission.USER_READ,

    // 사이트 관리 (삭제 제외)
    Permission.SITE_CREATE,
    Permission.SITE_READ,
    Permission.SITE_UPDATE,
    Permission.SITE_PUBLISH,

    // 섹션 관리
    Permission.SECTION_CREATE,
    Permission.SECTION_READ,
    Permission.SECTION_UPDATE,
    Permission.SECTION_DELETE,
    Permission.SECTION_PUBLISH,

    // 템플릿 관리
    Permission.TEMPLATE_CREATE,
    Permission.TEMPLATE_READ,
    Permission.TEMPLATE_UPDATE,
    Permission.TEMPLATE_DELETE,
    Permission.TEMPLATE_PUBLISH,

    // 파일 관리
    Permission.FILE_UPLOAD,
    Permission.FILE_READ,
    Permission.FILE_DELETE,
  ],

  [UserRole.VIEWER]: [
    // 읽기 전용 권한
    Permission.USER_READ,
    Permission.SITE_READ,
    Permission.SECTION_READ,
    Permission.TEMPLATE_READ,
    Permission.FILE_READ,
  ],

  [UserRole.GUEST]: [
    // 공개 콘텐츠만 읽기
    Permission.SITE_READ,
    Permission.SECTION_READ,
  ],
};

// 리소스별 권한 그룹
export const RESOURCE_PERMISSIONS = {
  USER: [
    Permission.USER_CREATE,
    Permission.USER_READ,
    Permission.USER_UPDATE,
    Permission.USER_DELETE,
    Permission.USER_MANAGE_ROLES,
  ],
  SITE: [
    Permission.SITE_CREATE,
    Permission.SITE_READ,
    Permission.SITE_UPDATE,
    Permission.SITE_DELETE,
    Permission.SITE_PUBLISH,
  ],
  SECTION: [
    Permission.SECTION_CREATE,
    Permission.SECTION_READ,
    Permission.SECTION_UPDATE,
    Permission.SECTION_DELETE,
    Permission.SECTION_PUBLISH,
  ],
  TEMPLATE: [
    Permission.TEMPLATE_CREATE,
    Permission.TEMPLATE_READ,
    Permission.TEMPLATE_UPDATE,
    Permission.TEMPLATE_DELETE,
    Permission.TEMPLATE_PUBLISH,
  ],
  FILE: [Permission.FILE_UPLOAD, Permission.FILE_READ, Permission.FILE_DELETE],
  SYSTEM: [
    Permission.SYSTEM_SETTINGS,
    Permission.SYSTEM_AUDIT,
    Permission.SYSTEM_BACKUP,
  ],
  TENANT: [
    Permission.TENANT_CREATE,
    Permission.TENANT_READ,
    Permission.TENANT_UPDATE,
    Permission.TENANT_DELETE,
  ],
};

/**
 * 사용자 역할에 특정 권한이 있는지 확인
 */
export function hasPermission(
  userRole: UserRole,
  permission: Permission
): boolean {
  const rolePermissions = ROLE_PERMISSIONS[userRole];
  return rolePermissions.includes(permission);
}

/**
 * 사용자 역할에 여러 권한이 모두 있는지 확인
 */
export function hasAllPermissions(
  userRole: UserRole,
  permissions: Permission[]
): boolean {
  return permissions.every((permission) => hasPermission(userRole, permission));
}

/**
 * 사용자 역할에 권한 중 하나라도 있는지 확인
 */
export function hasAnyPermission(
  userRole: UserRole,
  permissions: Permission[]
): boolean {
  return permissions.some((permission) => hasPermission(userRole, permission));
}

/**
 * 특정 리소스에 대한 권한 확인
 */
export function hasResourcePermission(
  userRole: UserRole,
  resource: keyof typeof RESOURCE_PERMISSIONS,
  action:
    | "create"
    | "read"
    | "update"
    | "delete"
    | "publish"
    | "manage_roles"
    | "upload"
): boolean {
  const resourcePermissions = RESOURCE_PERMISSIONS[resource];
  const permission = resourcePermissions.find((p) => p.includes(action));

  if (!permission) {
    return false;
  }

  return hasPermission(userRole, permission);
}

/**
 * 사용자가 다른 사용자를 관리할 수 있는지 확인
 */
export function canManageUser(
  managerRole: UserRole,
  targetRole: UserRole
): boolean {
  // 관리자는 모든 사용자 관리 가능
  if (managerRole === UserRole.ADMIN) {
    return true;
  }

  // 편집자는 뷰어와 게스트만 관리 가능
  if (managerRole === UserRole.EDITOR) {
    return targetRole === UserRole.VIEWER || targetRole === UserRole.GUEST;
  }

  // 뷰어와 게스트는 다른 사용자 관리 불가
  return false;
}

/**
 * 역할 계층 구조 확인
 */
export function isHigherRole(role1: UserRole, role2: UserRole): boolean {
  const roleHierarchy = {
    [UserRole.ADMIN]: 4,
    [UserRole.EDITOR]: 3,
    [UserRole.VIEWER]: 2,
    [UserRole.GUEST]: 1,
  };

  return roleHierarchy[role1] > roleHierarchy[role2];
}

/**
 * 권한 기반 필터링
 */
export function filterByPermission<
  T extends { userId?: string; createdById?: string }
>(items: T[], userRole: UserRole, userId: string, permission: Permission): T[] {
  // 권한이 없으면 빈 배열 반환
  if (!hasPermission(userRole, permission)) {
    return [];
  }

  // 관리자는 모든 항목 접근 가능
  if (userRole === UserRole.ADMIN) {
    return items;
  }

  // 편집자는 자신이 생성한 항목과 뷰어가 생성한 항목 접근 가능
  if (userRole === UserRole.EDITOR) {
    return items.filter(
      (item) =>
        item.userId === userId ||
        item.createdById === userId ||
        // 뷰어가 생성한 항목도 편집 가능 (별도 로직 필요)
        true
    );
  }

  // 뷰어는 자신이 생성한 항목만 접근 가능
  if (userRole === UserRole.VIEWER) {
    return items.filter(
      (item) => item.userId === userId || item.createdById === userId
    );
  }

  // 게스트는 공개 항목만 접근 가능
  return [];
}

/**
 * API 엔드포인트별 필요 권한 매핑
 */
export const API_PERMISSIONS: Record<string, Permission[]> = {
  // 사용자 관리 API
  "POST /api/users": [Permission.USER_CREATE],
  "GET /api/users": [Permission.USER_READ],
  "PUT /api/users/:id": [Permission.USER_UPDATE],
  "DELETE /api/users/:id": [Permission.USER_DELETE],
  "PUT /api/users/:id/role": [Permission.USER_MANAGE_ROLES],

  // 사이트 관리 API
  "POST /api/sites": [Permission.SITE_CREATE],
  "GET /api/sites": [Permission.SITE_READ],
  "PUT /api/sites/:id": [Permission.SITE_UPDATE],
  "DELETE /api/sites/:id": [Permission.SITE_DELETE],
  "POST /api/sites/:id/publish": [Permission.SITE_PUBLISH],

  // 섹션 관리 API
  "POST /api/sections": [Permission.SECTION_CREATE],
  "GET /api/sections": [Permission.SECTION_READ],
  "PUT /api/sections/:id": [Permission.SECTION_UPDATE],
  "DELETE /api/sections/:id": [Permission.SECTION_DELETE],
  "POST /api/sections/:id/publish": [Permission.SECTION_PUBLISH],

  // 템플릿 관리 API
  "POST /api/templates": [Permission.TEMPLATE_CREATE],
  "GET /api/templates": [Permission.TEMPLATE_READ],
  "PUT /api/templates/:id": [Permission.TEMPLATE_UPDATE],
  "DELETE /api/templates/:id": [Permission.TEMPLATE_DELETE],
  "POST /api/templates/:id/publish": [Permission.TEMPLATE_PUBLISH],

  // 파일 관리 API
  "POST /api/files/upload": [Permission.FILE_UPLOAD],
  "GET /api/files": [Permission.FILE_READ],
  "DELETE /api/files/:id": [Permission.FILE_DELETE],

  // 시스템 관리 API
  "GET /api/admin/settings": [Permission.SYSTEM_SETTINGS],
  "PUT /api/admin/settings": [Permission.SYSTEM_SETTINGS],
  "GET /api/admin/audit": [Permission.SYSTEM_AUDIT],
  "POST /api/admin/backup": [Permission.SYSTEM_BACKUP],
};

/**
 * API 경로에 대한 권한 확인
 */
export function hasApiPermission(
  userRole: UserRole,
  method: string,
  path: string
): boolean {
  const apiKey = `${method} ${path}`;
  const requiredPermissions = API_PERMISSIONS[apiKey];

  if (!requiredPermissions) {
    // 정의되지 않은 API는 기본적으로 접근 거부
    return false;
  }

  return hasAnyPermission(userRole, requiredPermissions);
}

/**
 * 권한 기반 UI 컴포넌트 표시 여부 결정
 */
export function shouldShowComponent(
  userRole: UserRole,
  requiredPermissions: Permission[]
): boolean {
  return hasAnyPermission(userRole, requiredPermissions);
}

/**
 * 권한 기반 메뉴 필터링
 */
export interface MenuItem {
  id: string;
  label: string;
  path: string;
  requiredPermissions: Permission[];
  children?: MenuItem[];
}

export function filterMenuItems(
  menuItems: MenuItem[],
  userRole: UserRole
): MenuItem[] {
  return menuItems
    .filter((item) => hasAnyPermission(userRole, item.requiredPermissions))
    .map((item) => ({
      ...item,
      children: item.children
        ? filterMenuItems(item.children, userRole)
        : undefined,
    }));
}
