import type { Employee, EmployeePermissionKey, EmployeePermissionProfile, SystemRole } from '@/lib/types';

type PermissionDefinition = {
  key: EmployeePermissionKey;
  label: string;
  description: string;
  roles: SystemRole[];
};

export const EMPLOYEE_PERMISSION_DEFINITIONS: PermissionDefinition[] = [
  { key: 'admin.dashboard', label: 'لوحة الإدارة', description: 'الوصول إلى لوحة التحكم الإدارية.', roles: ['admin'] },
  { key: 'admin.employees', label: 'الموظفون', description: 'إدارة الموظفين وتعديل بياناتهم.', roles: ['admin'] },
  { key: 'admin.leave-requests', label: 'طلبات الإجازات', description: 'متابعة واعتماد طلبات الإجازات وتبديل الورديات.', roles: ['admin'] },
  { key: 'admin.advance-requests', label: 'طلبات السلف', description: 'مراجعة واعتماد طلبات السلف.', roles: ['admin'] },
  { key: 'admin.shifts', label: 'إدارة الورديات', description: 'إدارة الورديات والجداول.', roles: ['admin'] },
  { key: 'admin.hr-attendance', label: 'إدارة الحضور', description: 'إدارة تسجيلات الحضور والدوام والتكامل مع أجهزة البصمة.', roles: ['admin'] },
  { key: 'admin.production', label: 'الإنتاج', description: 'الدخول إلى شاشة الإنتاج.', roles: ['admin'] },
  { key: 'admin.sales', label: 'المبيعات', description: 'الوصول إلى إدارة المبيعات.', roles: ['admin'] },
  { key: 'admin.pos', label: 'نقطة البيع', description: 'استخدام شاشة نقطة البيع.', roles: ['admin', 'pos'] },
  { key: 'admin.purchases', label: 'المشتريات', description: 'إدارة فواتير وعمليات المشتريات.', roles: ['admin'] },
  { key: 'admin.checks', label: 'الشيكات', description: 'الوصول إلى إدارة الشيكات.', roles: ['admin'] },
  { key: 'admin.expense-recurring', label: 'المصاريف الدورية', description: 'إدارة القوالب الدورية واعتمادها وترحيلها.', roles: ['admin'] },
  { key: 'admin.work-tasks', label: 'مهام العمل الإدارية', description: 'اعتماد ومتابعة مهام العمل والتحويلات.', roles: ['admin'] },
  { key: 'admin.accounting', label: 'المحاسبة', description: 'الوصول إلى شجرة الحسابات والقيود.', roles: ['admin'] },
  { key: 'admin.monitoring', label: 'المراقبة', description: 'الوصول إلى لوحة مراقبة الحركات والتنبيهات.', roles: ['admin'] },
  { key: 'admin.materials', label: 'قوائم الأصناف', description: 'إدارة المواد والأصناف.', roles: ['admin'] },
  { key: 'admin.parties', label: 'العملاء والموردون', description: 'إدارة الأطراف التجارية.', roles: ['admin'] },
  { key: 'admin.cancel-invoices', label: 'إلغاء الفواتير', description: 'صلاحية خاصة لإلغاء الفواتير (تتطلب موافقة مدير النظام).', roles: ['admin'] },
  { key: 'settings.manage', label: 'الإعدادات العامة', description: 'إدارة إعدادات النظام وملفات الصلاحيات.', roles: ['admin'] },
  { key: 'employee.dashboard', label: 'لوحة الموظف', description: 'الوصول إلى لوحة الموظف الرئيسية.', roles: ['employee'] },
  { key: 'employee.statement', label: 'كشف الحساب', description: 'عرض كشف الحساب للموظف.', roles: ['employee'] },
  { key: 'employee.leave', label: 'طلب إجازة', description: 'إنشاء طلبات الإجازة.', roles: ['employee'] },
  { key: 'employee.advance', label: 'طلب سلفة', description: 'إنشاء طلبات السلفة.', roles: ['employee'] },
  { key: 'employee.shift-swap', label: 'تبديل وردية', description: 'إرسال طلبات تبديل الورديات.', roles: ['employee'] },
  { key: 'employee.work-tasks', label: 'مهام العمل', description: 'الوصول إلى مهام العمل.', roles: ['employee'] },
  { key: 'employee.my-tasks', label: 'مهامي', description: 'عرض المهام المسندة للموظف.', roles: ['employee'] },
];

const ALL_PERMISSION_KEYS = EMPLOYEE_PERMISSION_DEFINITIONS.map((entry) => entry.key);

const DEFAULT_PROFILES: EmployeePermissionProfile[] = [
  {
    id: 'admin-full',
    name: 'مدير النظام',
    description: 'وصول كامل إلى جميع أقسام الإدارة والإعدادات.',
    role: 'admin',
    permissions: ALL_PERMISSION_KEYS.filter((key) => key.startsWith('admin.') || key === 'settings.manage') as EmployeePermissionKey[],
  },
  {
    id: 'admin-hr',
    name: 'مدير الموارد البشرية',
    description: 'إدارة الموظفين والإجازات والسلف والورديات والحضور.',
    role: 'admin',
    permissions: ['admin.dashboard', 'admin.monitoring', 'admin.employees', 'admin.leave-requests', 'admin.advance-requests', 'admin.shifts', 'admin.hr-attendance'],
  },
  {
    id: 'admin-accountant',
    name: 'محاسب',
    description: 'وصول إلى المحاسبة والشيكات والموردين والمشتريات.',
    role: 'admin',
    permissions: ['admin.dashboard', 'admin.monitoring', 'admin.accounting', 'admin.checks', 'admin.expense-recurring', 'admin.purchases', 'admin.parties'],
  },
  {
    id: 'admin-purchasing',
    name: 'مسؤول مشتريات',
    description: 'وصول إلى المشتريات والأصناف والأطراف.',
    role: 'admin',
    permissions: ['admin.dashboard', 'admin.monitoring', 'admin.purchases', 'admin.materials', 'admin.parties'],
  },
  {
    id: 'employee-standard',
    name: 'موظف عادي',
    description: 'صلاحيات الخدمة الذاتية الأساسية للموظف.',
    role: 'employee',
    permissions: ['employee.dashboard', 'employee.statement', 'employee.leave', 'employee.advance', 'employee.shift-swap', 'employee.work-tasks', 'employee.my-tasks'],
  },
  {
    id: 'employee-warehouse',
    name: 'موظف مستودع',
    description: 'صلاحيات مركزة على مهام العمل والمتابعة اليومية.',
    role: 'employee',
    permissions: ['employee.dashboard', 'employee.work-tasks', 'employee.my-tasks'],
  },
  {
    id: 'pos-cashier',
    name: 'كاشير نقطة بيع',
    description: 'الوصول إلى شاشة نقطة البيع فقط.',
    role: 'pos',
    permissions: ['admin.pos'],
  },
];

function toRole(value: unknown): SystemRole | null {
  return value === 'admin' || value === 'employee' || value === 'pos' ? value : null;
}

function toPermissionKey(value: unknown): EmployeePermissionKey | null {
  return typeof value === 'string' && ALL_PERMISSION_KEYS.includes(value as EmployeePermissionKey)
    ? (value as EmployeePermissionKey)
    : null;
}

function dedupePermissions(values: EmployeePermissionKey[]): EmployeePermissionKey[] {
  return Array.from(new Set(values));
}

function normalizeProfile(entry: unknown): EmployeePermissionProfile | null {
  if (!entry || typeof entry !== 'object') return null;

  const item = entry as Record<string, unknown>;
  const role = toRole(item.role);
  const id = String(item.id || '').trim();
  const name = String(item.name || '').trim();
  if (!role || !id || !name) return null;

  const permissions = Array.isArray(item.permissions)
    ? dedupePermissions(item.permissions.map(toPermissionKey).filter((value): value is EmployeePermissionKey => Boolean(value)))
    : [];

  return {
    id,
    name,
    description: String(item.description || '').trim() || undefined,
    role,
    permissions,
  };
}

export function getDefaultEmployeePermissionProfiles(): EmployeePermissionProfile[] {
  return DEFAULT_PROFILES.map((profile) => ({ ...profile, permissions: [...profile.permissions] }));
}

export function getEmployeePermissionProfilesFromSettings(settings: Record<string, any> | null | undefined): EmployeePermissionProfile[] {
  const normalized = Array.isArray(settings?.employeePermissionProfiles)
    ? settings?.employeePermissionProfiles.map(normalizeProfile).filter((profile): profile is EmployeePermissionProfile => Boolean(profile))
    : [];

  return normalized.length > 0 ? normalized : getDefaultEmployeePermissionProfiles();
}

export function getPermissionDefinitionsForRole(role: SystemRole): PermissionDefinition[] {
  return EMPLOYEE_PERMISSION_DEFINITIONS.filter((entry) => entry.roles.includes(role));
}

export function findPermissionProfileById(settings: Record<string, any> | null | undefined, profileId?: string | null) {
  const normalizedProfileId = String(profileId || '').trim();
  if (!normalizedProfileId) return null;

  return getEmployeePermissionProfilesFromSettings(settings).find((profile) => profile.id === normalizedProfileId) || null;
}

export function getDefaultPermissionProfileForRole(role: SystemRole, settings?: Record<string, any> | null) {
  return getEmployeePermissionProfilesFromSettings(settings).find((profile) => profile.role === role) || null;
}

export function getEffectivePermissionProfile(employee: Pick<Employee, 'role' | 'permissionProfileId'>, settings?: Record<string, any> | null) {
  const explicit = findPermissionProfileById(settings, employee.permissionProfileId);
  if (explicit && explicit.role === employee.role) {
    return explicit;
  }

  return getDefaultPermissionProfileForRole(employee.role, settings);
}

export function getEmployeePermissions(employee: Pick<Employee, 'role' | 'permissionProfileId'>, settings?: Record<string, any> | null): EmployeePermissionKey[] {
  const profile = getEffectivePermissionProfile(employee, settings);
  if (profile) {
    return [...profile.permissions];
  }

  return [];
}

export function hasEmployeePermission(
  employee: Pick<Employee, 'role' | 'permissionProfileId'> | null | undefined,
  settings: Record<string, any> | null | undefined,
  permission: EmployeePermissionKey,
) {
  if (!employee) return false;
  return getEmployeePermissions(employee, settings).includes(permission);
}

export function getEmployeeLandingPath(employee: Pick<Employee, 'role' | 'permissionProfileId'> | null | undefined, settings?: Record<string, any> | null) {
  if (!employee) return '/login';

  const permissions = getEmployeePermissions(employee, settings);
  const prioritizedPaths: Array<{ permission: EmployeePermissionKey; path: string }> = [
    { permission: 'admin.dashboard', path: '/admin/dashboard' },
    { permission: 'admin.employees', path: '/admin/employees' },
    { permission: 'admin.purchases', path: '/admin/purchases' },
    { permission: 'admin.sales', path: '/admin/sales' },
    { permission: 'admin.pos', path: '/admin/sales/pos' },
    { permission: 'admin.accounting', path: '/admin/accounting/chart' },
    { permission: 'admin.expense-recurring', path: '/admin/accounting/expense-recurring' },
    { permission: 'settings.manage', path: '/settings' },
    { permission: 'employee.dashboard', path: '/employee/dashboard' },
    { permission: 'employee.work-tasks', path: '/employee/work-tasks' },
    { permission: 'employee.my-tasks', path: '/employee/my-tasks' },
  ];

  const match = prioritizedPaths.find((entry) => permissions.includes(entry.permission));
  if (match) return match.path;

  if (employee.role === 'pos') return '/admin/sales/pos';
  if (employee.role === 'admin') return '/admin/dashboard';
  return '/employee/dashboard';
}