import {
  ownerPermissionsForOrgType,
  type OrganizationTypeName,
} from './organization-type';
import { normalizeTabPermissions } from './permissions';

export const CLINIC_PARTICIPATION_PERMISSIONS = [
  'TAB_TREATMENT_READ',
  'TAB_TREATMENT_EDIT',
] as const;

export const LAB_PARTICIPATION_PERMISSIONS = [
  'TAB_TASKS_READ',
  'TAB_TASKS_EDIT',
] as const;

const CLINIC_PARTICIPATION_SET = new Set<string>(CLINIC_PARTICIPATION_PERMISSIONS);
const LAB_PARTICIPATION_SET = new Set<string>(LAB_PARTICIPATION_PERMISSIONS);

export type MembershipWithPermissions = {
  isOwner: boolean;
  organization: {
    plan?: { name: string; maxUsers?: number; price?: number } | null;
    planId?: string | null;
    type?: { name: string };
  };
  permissions?: Array<{ permission: { name: string } }>;
};

export function getOrgTypeFromMembership(
  membership: MembershipWithPermissions,
): OrganizationTypeName {
  return membership.organization.type?.name === 'LAB' ? 'LAB' : 'CLINIC';
}

export function hasActivePlan(membership: MembershipWithPermissions): boolean {
  if (membership.organization.plan != null) {
    return true;
  }
  return Boolean(membership.organization.planId);
}

export function getStoredPermissionNames(
  membership: MembershipWithPermissions,
): string[] {
  return membership.permissions?.map((p) => p.permission.name) ?? [];
}

export function getEffectivePermissionNames(
  membership: MembershipWithPermissions,
): string[] {
  const stored = getStoredPermissionNames(membership);

  if (!membership.isOwner) {
    return normalizeTabPermissions(stored);
  }

  const orgType = getOrgTypeFromMembership(membership);
  const base = ownerPermissionsForOrgType(orgType, hasActivePlan(membership));
  return normalizeTabPermissions([...base, ...stored]);
}

export function hasEffectivePermission(
  membership: MembershipWithPermissions,
  permission: string,
): boolean {
  return getEffectivePermissionNames(membership).includes(permission);
}

export function participationPermissionsForOrgType(
  orgType: OrganizationTypeName,
): readonly string[] {
  return orgType === 'LAB'
    ? LAB_PARTICIPATION_PERMISSIONS
    : CLINIC_PARTICIPATION_PERMISSIONS;
}

export function participatesInTreatments(
  membership: MembershipWithPermissions,
): boolean {
  if (getOrgTypeFromMembership(membership) !== 'CLINIC') {
    return false;
  }
  return getStoredPermissionNames(membership).includes('TAB_TREATMENT_EDIT');
}

export function participatesInTasks(membership: MembershipWithPermissions): boolean {
  if (getOrgTypeFromMembership(membership) !== 'LAB') {
    return false;
  }
  return getStoredPermissionNames(membership).includes('TAB_TASKS_EDIT');
}

export function isParticipationPermission(name: string): boolean {
  return CLINIC_PARTICIPATION_SET.has(name) || LAB_PARTICIPATION_SET.has(name);
}
