export type PermissionControlType = 'toggle' | 'scope';

export interface PermissionDefinition {
  key: string;
  label: string;
  type: PermissionControlType;
  description?: string;
}

export interface PermissionModuleDefinition {
  id: string;
  label: string;
  description?: string;
  permissions: PermissionDefinition[];
}

export const PERMISSION_MODULES: PermissionModuleDefinition[] = [
  {
    id: 'leave',
    label: 'Leave Management',
    description: 'Control leave requests, approvals, and visibility.',
    permissions: [
      {
        key: 'leave.access',
        label: 'Module access',
        type: 'toggle',
        description: 'Can open the Leave Management page.',
      },
      {
        key: 'leave.view',
        label: 'View requests',
        type: 'scope',
        description: 'Whose leave requests can be viewed.',
      },
      {
        key: 'leave.create',
        label: 'Create requests',
        type: 'scope',
        description: 'Who leave requests can be created for.',
      },
      {
        key: 'leave.update',
        label: 'Update requests',
        type: 'scope',
        description: 'Whose leave requests can be edited.',
      },
      {
        key: 'leave.delete',
        label: 'Delete requests',
        type: 'scope',
        description: 'Whose leave requests can be deleted.',
      },
      {
        key: 'leave.approve',
        label: 'Approve / reject',
        type: 'toggle',
        description: 'Can approve or reject leave requests.',
      },
    ],
  },
  {
    id: 'attendance',
    label: 'Attendance',
    permissions: [
      { key: 'attendance.access', label: 'Module access', type: 'toggle' },
      {
        key: 'attendance.view',
        label: 'View attendance',
        type: 'scope',
      },
      {
        key: 'attendance.manage',
        label: 'Manage attendance',
        type: 'toggle',
        description: 'Can update attendance records for others.',
      },
      {
        key: 'attendance.request.create',
        label: 'Create attendance requests',
        type: 'scope',
      },
      {
        key: 'attendance.request.view',
        label: 'View attendance requests',
        type: 'scope',
      },
      {
        key: 'attendance.request.approve',
        label: 'Approve / reject attendance requests',
        type: 'toggle',
      },
    ],
  },
  {
    id: 'members',
    label: 'Members',
    permissions: [
      { key: 'members.access', label: 'Module access', type: 'toggle' },
      { key: 'members.view', label: 'View members', type: 'scope' },
      { key: 'members.create', label: 'Create members', type: 'toggle' },
      { key: 'members.update', label: 'Update members', type: 'scope' },
      { key: 'members.delete', label: 'Delete members', type: 'scope' },
    ],
  },
  {
    id: 'reports',
    label: 'Reports',
    permissions: [
      { key: 'reports.access', label: 'Module access', type: 'toggle' },
      { key: 'reports.view', label: 'View reports', type: 'scope' },
      { key: 'reports.export', label: 'Export reports', type: 'toggle' },
    ],
  },
  {
    id: 'dashboard',
    label: 'Dashboard',
    permissions: [
      { key: 'dashboard.access', label: 'Module access', type: 'toggle' },
      { key: 'dashboard.view', label: 'View dashboard', type: 'scope' },
    ],
  },
  {
    id: 'calendar',
    label: 'Calendar',
    permissions: [
      { key: 'calendar.access', label: 'Module access', type: 'toggle' },
      { key: 'calendar.view', label: 'View calendar', type: 'scope' },
    ],
  },
  {
    id: 'holidays',
    label: 'Holidays',
    permissions: [
      { key: 'holidays.access', label: 'Module access', type: 'toggle' },
      { key: 'holidays.view', label: 'View holidays', type: 'scope' },
      { key: 'holidays.create', label: 'Create holidays', type: 'scope' },
      { key: 'holidays.update', label: 'Update holidays', type: 'scope' },
      { key: 'holidays.delete', label: 'Delete holidays', type: 'scope' },
    ],
  },
  {
    id: 'notice',
    label: 'Notice',
    permissions: [
      { key: 'notice.access', label: 'Module access', type: 'toggle' },
      { key: 'notice.view', label: 'View notices', type: 'scope' },
      { key: 'notice.create', label: 'Create notices', type: 'scope' },
      { key: 'notice.update', label: 'Update notices', type: 'scope' },
      { key: 'notice.delete', label: 'Delete notices', type: 'scope' },
    ],
  },
  {
    id: 'settings',
    label: 'Settings',
    permissions: [
      { key: 'settings.access', label: 'Module access', type: 'toggle' },
      { key: 'settings.manage', label: 'Manage settings', type: 'toggle' },
    ],
  },
  {
    id: 'general',
    label: 'General Data',
    permissions: [
      { key: 'general.access', label: 'Module access', type: 'toggle' },
      { key: 'general.manage', label: 'Manage master data', type: 'toggle' },
    ],
  },
  {
    id: 'permissions',
    label: 'Access Control',
    permissions: [
      { key: 'permissions.access', label: 'Module access', type: 'toggle' },
      {
        key: 'permissions.manage',
        label: 'Manage roles & permissions',
        type: 'toggle',
      },
    ],
  },
  {
    id: 'recruitment',
    label: 'Recruitment',
    description: 'Job postings, candidate pipeline, and hiring tasks.',
    permissions: [
      { key: 'recruitment.access', label: 'Module access', type: 'toggle' },
      { key: 'recruitment.view', label: 'View candidates & jobs', type: 'scope' },
      { key: 'recruitment.create', label: 'Create jobs & candidates', type: 'scope' },
      { key: 'recruitment.update', label: 'Update jobs & candidates', type: 'scope' },
      { key: 'recruitment.delete', label: 'Delete jobs & candidates', type: 'scope' },
      {
        key: 'recruitment.manage',
        label: 'Manage pipeline stages',
        type: 'toggle',
      },
      {
        key: 'recruitment.api_keys',
        label: 'Manage tenant API keys',
        type: 'toggle',
      },
    ],
  },
];

export const ALL_PERMISSION_KEYS = PERMISSION_MODULES.flatMap((module) =>
  module.permissions.map((permission) => permission.key),
);

export const SCOPE_KEYS = PERMISSION_MODULES.flatMap((module) =>
  module.permissions
    .filter((permission) => permission.type === 'scope')
    .map((permission) => permission.key),
);

const TOGGLE_KEYS = PERMISSION_MODULES.flatMap((module) =>
  module.permissions
    .filter((permission) => permission.type === 'toggle')
    .map((permission) => permission.key),
);

export type PermissionValue =
  | 'true'
  | 'false'
  | 'none'
  | 'own'
  | 'all'
  | 'own_and_all';

export function isValidPermissionKey(key: string): boolean {
  return ALL_PERMISSION_KEYS.includes(key);
}

export function isValidPermissionValue(
  key: string,
  value: string,
): value is PermissionValue {
  if (SCOPE_KEYS.includes(key)) {
    return (
      value === 'none' ||
      value === 'own' ||
      value === 'all' ||
      value === 'own_and_all'
    );
  }

  if (TOGGLE_KEYS.includes(key)) {
    return value === 'true' || value === 'false';
  }

  return false;
}

function setScope(
  map: Record<string, PermissionValue>,
  key: string,
  value: PermissionValue,
) {
  map[key] = value;
}

function setToggle(
  map: Record<string, PermissionValue>,
  key: string,
  value: boolean,
) {
  map[key] = value ? 'true' : 'false';
}

function applyFullAccess(map: Record<string, PermissionValue>) {
  for (const key of TOGGLE_KEYS) {
    map[key] = 'true';
  }
  for (const key of SCOPE_KEYS) {
    map[key] = 'own_and_all';
  }
}

function applyOwnerDefaults(map: Record<string, PermissionValue>) {
  for (const key of TOGGLE_KEYS) {
    map[key] = 'true';
  }
  for (const key of SCOPE_KEYS) {
    map[key] = 'all';
  }
}

function applyMemberDefaults(map: Record<string, PermissionValue>) {
  setToggle(map, 'dashboard.access', true);
  setScope(map, 'dashboard.view', 'own');
  setToggle(map, 'attendance.access', true);
  setScope(map, 'attendance.view', 'own');
  setScope(map, 'attendance.request.create', 'own');
  setScope(map, 'attendance.request.view', 'own');
  setToggle(map, 'attendance.request.approve', false);
  setToggle(map, 'leave.access', true);
  setScope(map, 'leave.view', 'own');
  setScope(map, 'leave.create', 'own');
  setScope(map, 'leave.update', 'own');
  setScope(map, 'leave.delete', 'none');
  setToggle(map, 'leave.approve', false);
  setToggle(map, 'calendar.access', true);
  setScope(map, 'calendar.view', 'own');
  setToggle(map, 'holidays.access', true);
  setScope(map, 'holidays.view', 'own');
  setScope(map, 'holidays.create', 'own');
  setScope(map, 'holidays.update', 'own');
  setScope(map, 'holidays.delete', 'none');
  setToggle(map, 'notice.access', true);
  setScope(map, 'notice.view', 'own');
  setScope(map, 'notice.create', 'own');
  setScope(map, 'notice.update', 'own');
  setScope(map, 'notice.delete', 'none');
}

function applyAdminDefaults(map: Record<string, PermissionValue>) {
  applyFullAccess(map);
  setToggle(map, "settings.access", false);
  setToggle(map, "settings.manage", false);
  setToggle(map, "permissions.access", false);
  setToggle(map, "permissions.manage", false);
  setToggle(map, "recruitment.api_keys", false);
}

export function getDefaultPermissionMap(
  slug: string,
): Record<string, PermissionValue> {
  const map = ALL_PERMISSION_KEYS.reduce(
    (acc, key) => {
      acc[key] = SCOPE_KEYS.includes(key) ? 'none' : 'false';
      return acc;
    },
    {} as Record<string, PermissionValue>,
  );

  if (slug === 'owner') {
    applyOwnerDefaults(map);
    return map;
  }

  if (slug === 'admin') {
    applyAdminDefaults(map);
    return map;
  }

  if (slug === 'member') {
    applyMemberDefaults(map);
    return map;
  }

  return map;
}

export const SYSTEM_ROLE_TEMPLATES = [
  {
    name: 'Owner',
    slug: 'owner',
    description: 'Full access to all modules and settings.',
    is_system: true,
    hierarchy: 100,
  },
  {
    name: 'Admin',
    slug: 'admin',
    description: 'Broad access across the organization.',
    is_system: true,
    hierarchy: 50,
  },
  {
    name: 'Member',
    slug: 'member',
    description: 'Standard employee access.',
    is_system: true,
    hierarchy: 1,
  },
] as const;
