import { getModelByName } from '@adminjs/prisma';
import type { PrismaService } from '../../prisma/prisma.service';

type ResourceOptions = {
  navigation?: { name: string; icon?: string };
  properties?: Record<string, { isVisible?: boolean | { list?: boolean; filter?: boolean; show?: boolean; edit?: boolean } }>;
  actions?: Record<
    string,
    { isAccessible?: boolean }
  >;
};

type AdminResource = {
  resource: { model: ReturnType<typeof getModelByName>; client: PrismaService };
  options: ResourceOptions;
};

const hide = (...propertyNames: string[]): ResourceOptions['properties'] =>
  Object.fromEntries(
    propertyNames.map((name) => [
      name,
      { isVisible: { list: false, filter: false, show: false, edit: false } },
    ]),
  );

const catalogActions: ResourceOptions['actions'] = {
  new: { isAccessible: false },
  delete: { isAccessible: false },
  bulkDelete: { isAccessible: false },
};

function resource(
  client: PrismaService,
  modelName: string,
  options: ResourceOptions = {},
): AdminResource {
  return {
    resource: {
      model: getModelByName(modelName),
      client,
    },
    options,
  };
}

/** Curated AdminJS allowlist — keep in sync when adding ops-relevant Prisma models. */
export function buildAdminResources(prisma: PrismaService): AdminResource[] {
  return [
    // Identity
    resource(prisma, 'User', {
      navigation: { name: 'Identity', icon: 'User' },
      properties: hide('passwordHash'),
    }),
    resource(prisma, 'Session', {
      navigation: { name: 'Identity', icon: 'User' },
      properties: hide('token', 'refreshToken'),
    }),
    resource(prisma, 'PhoneVerificationCode', {
      navigation: { name: 'Identity', icon: 'User' },
      properties: hide('codeHash'),
    }),

    // Orgs & access
    resource(prisma, 'Organization', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
    }),
    resource(prisma, 'OrganizationType', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
    }),
    resource(prisma, 'Plan', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
    }),
    resource(prisma, 'Membership', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
    }),
    resource(prisma, 'Permission', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
    }),
    // MembershipPermission omitted: composite @@id — AdminJS list 500s without a single id
    resource(prisma, 'Feature', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
    }),
    resource(prisma, 'StaffInvitation', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
      properties: hide('tokenHash'),
    }),
    resource(prisma, 'OrganizationLink', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
    }),
    resource(prisma, 'OrganizationInvitation', {
      navigation: { name: 'Orgs & access', icon: 'Settings' },
      properties: hide('tokenHash'),
    }),

    // Clinic
    resource(prisma, 'Patient', {
      navigation: { name: 'Clinic', icon: 'Healthcare' },
    }),
    resource(prisma, 'Appointment', {
      navigation: { name: 'Clinic', icon: 'Healthcare' },
    }),
    resource(prisma, 'Treatment', {
      navigation: { name: 'Clinic', icon: 'Healthcare' },
    }),
    resource(prisma, 'TreatmentDetail', {
      navigation: { name: 'Clinic', icon: 'Healthcare' },
    }),
    resource(prisma, 'TreatmentDetailAttachment', {
      navigation: { name: 'Clinic', icon: 'Healthcare' },
    }),

    // Lab
    resource(prisma, 'LabCase', {
      navigation: { name: 'Lab', icon: 'Archive' },
      properties: hide('accessToken'),
    }),
    resource(prisma, 'LabCaseLine', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),
    // LabCaseDetail omitted: composite @@id — AdminJS list 500s without a single id
    // (inspect LabCase + TreatmentDetail instead)
    resource(prisma, 'LabCaseSend', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),
    resource(prisma, 'LabCaseToothProsthesis', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),
    resource(prisma, 'LabCaseTask', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),
    resource(prisma, 'LabCaseTaskStatusEvent', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),
    resource(prisma, 'LabCaseComment', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),
    resource(prisma, 'LabCaseActivity', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),
    resource(prisma, 'UserNotification', {
      navigation: { name: 'Lab', icon: 'Archive' },
    }),

    // Catalog — edit OK; create/delete via seed/migrations
    resource(prisma, 'TreatmentType', {
      navigation: { name: 'Catalog', icon: 'Catalog' },
      actions: catalogActions,
    }),
    resource(prisma, 'ProsthesisType', {
      navigation: { name: 'Catalog', icon: 'Catalog' },
      actions: catalogActions,
    }),
    resource(prisma, 'LabWorkflowStep', {
      navigation: { name: 'Catalog', icon: 'Catalog' },
      actions: catalogActions,
    }),
    resource(prisma, 'ProsthesisTypeStep', {
      navigation: { name: 'Catalog', icon: 'Catalog' },
      actions: catalogActions,
    }),
    resource(prisma, 'CatalogTranslation', {
      navigation: { name: 'Catalog', icon: 'Catalog' },
      actions: catalogActions,
    }),
  ];
}
