import type { AuditLogEntry } from "@workspace/api-client-react";

export type AuditTFunction = (
  key: string,
  options?: Record<string, unknown>,
) => string;

export function asRecord(value: unknown): Record<string, unknown> {
  return value && typeof value === "object" && !Array.isArray(value)
    ? (value as Record<string, unknown>)
    : {};
}

export function asString(v: unknown): string | null {
  return typeof v === "string" && v.trim() ? v : null;
}

export function asNumber(v: unknown): number | null {
  return typeof v === "number" && Number.isFinite(v) ? v : null;
}

export function unitLabel(
  t: AuditTFunction,
  kind: string,
  count: number,
): string {
  return t(`admin.audit.unit.${kind}`, { count });
}

export function appName(
  meta: Record<string, unknown>,
  lang: string,
  fallbackId: AuditLogEntry["targetId"],
): string {
  const en = asString(meta.nameEn) ?? asString(meta.appNameEn);
  const ar = asString(meta.nameAr) ?? asString(meta.appNameAr);
  const slug = asString(meta.slug) ?? asString(meta.appSlug);
  const preferred = lang === "ar" ? ar ?? en : en ?? ar;
  return preferred ?? slug ?? `#${fallbackId ?? "?"}`;
}

export function linkedAppName(
  meta: Record<string, unknown>,
  lang: string,
): string | null {
  const en = asString(meta.appNameEn);
  const ar = asString(meta.appNameAr);
  const slug = asString(meta.appSlug);
  return (lang === "ar" ? ar ?? en : en ?? ar) ?? slug ?? null;
}

export function plainName(
  meta: Record<string, unknown>,
  fallbackId: AuditLogEntry["targetId"],
): string {
  return asString(meta.name) ?? `#${fallbackId ?? "?"}`;
}

export function changeCount(meta: Record<string, unknown>): number {
  const changes = meta.changes;
  if (changes && typeof changes === "object" && !Array.isArray(changes)) {
    return Object.keys(changes as Record<string, unknown>).length;
  }
  if (Array.isArray(changes)) return changes.length;
  let count = 0;
  for (const key of ["members", "apps", "roles"]) {
    const diff = meta[key];
    if (diff && typeof diff === "object" && !Array.isArray(diff)) {
      const d = diff as Record<string, unknown>;
      const added = Array.isArray(d.added) ? d.added.length : 0;
      const removed = Array.isArray(d.removed) ? d.removed.length : 0;
      if (added + removed > 0) count += 1;
    }
  }
  return count;
}

export function formatAuditSummary(
  entry: AuditLogEntry,
  t: AuditTFunction,
  lang: string,
): string | null {
  const action = entry.action;
  const meta = asRecord(entry.metadata);
  const targetId = entry.targetId;

  switch (action) {
    case "app.create":
      return t("admin.audit.summary.app.create", {
        name: appName(meta, lang, targetId),
      });
    case "app.update": {
      const name = appName(meta, lang, targetId);
      const changes = asRecord(meta.changes);
      const order = lang === "ar"
        ? ["nameAr", "nameEn", "slug"]
        : ["nameEn", "nameAr", "slug"];
      for (const field of order) {
        if (!(field in changes)) continue;
        const change = asRecord(changes[field]);
        const previousName = asString(change.from);
        const nextName = asString(change.to);
        if (previousName && nextName && previousName !== nextName) {
          return t("admin.audit.summary.app.rename", {
            previousName,
            name: nextName,
          });
        }
      }
      return t("admin.audit.summary.app.update", {
        name,
        changes: unitLabel(t, "change", changeCount(meta)),
      });
    }
    case "app.permission.add":
      return t("admin.audit.summary.app.permissionAdd", {
        name: appName(meta, lang, targetId),
        permission:
          asString(meta.permissionName) ??
          (asNumber(meta.permissionId) != null ? `#${meta.permissionId}` : "?"),
      });
    case "app.permission.remove":
      return t("admin.audit.summary.app.permissionRemove", {
        name: appName(meta, lang, targetId),
        permission:
          asString(meta.permissionName) ??
          (asNumber(meta.permissionId) != null ? `#${meta.permissionId}` : "?"),
      });
    case "app.delete": {
      const name = appName(meta, lang, targetId);
      if (meta.force) {
        const groupCount = asNumber(meta.groupCount) ?? 0;
        return t("admin.audit.summary.app.forceDelete", {
          name,
          groups: unitLabel(t, "group", groupCount),
        });
      }
      return t("admin.audit.summary.app.delete", { name });
    }
    case "auth.issue_reset_link":
      return t("admin.audit.summary.auth.issueResetLink", {
        username: asString(meta.username) ?? `#${targetId ?? "?"}`,
      });
    case "group.create":
      return t("admin.audit.summary.group.create", {
        name: plainName(meta, targetId),
        members: unitLabel(t, "member", asNumber(meta.memberCount) ?? 0),
        apps: unitLabel(t, "app", asNumber(meta.appCount) ?? 0),
      });
    case "group.update": {
      const name = plainName(meta, targetId);
      const previousName = asString(meta.previousName);
      const fieldsChanged = changeCount(meta);
      if (previousName && previousName !== name && fieldsChanged <= 1) {
        return t("admin.audit.summary.group.rename", {
          previousName,
          name,
        });
      }
      return t("admin.audit.summary.group.update", {
        name,
        changes: unitLabel(t, "change", Math.max(1, fieldsChanged)),
      });
    }
    case "group.delete": {
      const name = plainName(meta, targetId);
      if (meta.force) {
        const memberCount = asNumber(meta.memberCount) ?? 0;
        return t("admin.audit.summary.group.forceDelete", {
          name,
          members: unitLabel(t, "member", memberCount),
        });
      }
      return t("admin.audit.summary.group.delete", { name });
    }
    case "group.user.add": {
      const groupName = asString(meta.groupName) ?? `#${targetId ?? "?"}`;
      const username = asString(meta.username);
      return username
        ? t("admin.audit.summary.group.userAdd", { name: groupName, username })
        : t("admin.audit.summary.group.userAddById", {
            name: groupName,
            userId: asNumber(meta.userId) ?? "?",
          });
    }
    case "group.user.remove": {
      const groupName = asString(meta.groupName) ?? `#${targetId ?? "?"}`;
      const username = asString(meta.username);
      return username
        ? t("admin.audit.summary.group.userRemove", { name: groupName, username })
        : t("admin.audit.summary.group.userRemoveById", {
            name: groupName,
            userId: asNumber(meta.userId) ?? "?",
          });
    }
    case "group.app.add": {
      const groupName = asString(meta.groupName) ?? `#${targetId ?? "?"}`;
      const appNm = linkedAppName(meta, lang);
      return appNm
        ? t("admin.audit.summary.group.appAdd", { name: groupName, appName: appNm })
        : t("admin.audit.summary.group.appAddById", {
            name: groupName,
            appId: asNumber(meta.appId) ?? "?",
          });
    }
    case "group.app.remove": {
      const groupName = asString(meta.groupName) ?? `#${targetId ?? "?"}`;
      const appNm = linkedAppName(meta, lang);
      return appNm
        ? t("admin.audit.summary.group.appRemove", { name: groupName, appName: appNm })
        : t("admin.audit.summary.group.appRemoveById", {
            name: groupName,
            appId: asNumber(meta.appId) ?? "?",
          });
    }
    case "group.role.add": {
      const groupName = asString(meta.groupName) ?? `#${targetId ?? "?"}`;
      const roleName = asString(meta.roleName);
      return roleName
        ? t("admin.audit.summary.group.roleAdd", { name: groupName, roleName })
        : t("admin.audit.summary.group.roleAddById", {
            name: groupName,
            roleId: asNumber(meta.roleId) ?? "?",
          });
    }
    case "group.role.remove": {
      const groupName = asString(meta.groupName) ?? `#${targetId ?? "?"}`;
      const roleName = asString(meta.roleName);
      return roleName
        ? t("admin.audit.summary.group.roleRemove", { name: groupName, roleName })
        : t("admin.audit.summary.group.roleRemoveById", {
            name: groupName,
            roleId: asNumber(meta.roleId) ?? "?",
          });
    }
    case "role.create":
      return t("admin.audit.summary.role.create", {
        name: plainName(meta, targetId),
      });
    case "role.update": {
      const previousName = asString(meta.previousName);
      const name = plainName(meta, targetId);
      if (previousName && previousName !== name) {
        return t("admin.audit.summary.role.rename", {
          previousName,
          name,
        });
      }
      return t("admin.audit.summary.role.update", {
        name,
        changes: unitLabel(t, "change", Math.max(1, changeCount(meta))),
      });
    }
    case "role.delete":
      return t("admin.audit.summary.role.delete", {
        name:
          asString(meta.roleName) ??
          asString(meta.name) ??
          `#${targetId ?? "?"}`,
      });
    case "role.permissions.replace": {
      const added = Array.isArray(meta.added) ? meta.added.length : 0;
      const removed = Array.isArray(meta.removed) ? meta.removed.length : 0;
      return t("admin.audit.summary.role.permissionsReplace", {
        name: asString(meta.roleName) ?? `#${targetId ?? "?"}`,
        added: unitLabel(t, "permission", added),
        removed: unitLabel(t, "permission", removed),
      });
    }
    case "role.permission.add":
      return t("admin.audit.summary.role.permissionAdd", {
        name: asString(meta.roleName) ?? `#${targetId ?? "?"}`,
        permission:
          asString(meta.permissionName) ??
          (asNumber(meta.permissionId) != null ? `#${meta.permissionId}` : "?"),
      });
    case "role.permission.remove":
      return t("admin.audit.summary.role.permissionRemove", {
        name: asString(meta.roleName) ?? `#${targetId ?? "?"}`,
        permission:
          asString(meta.permissionName) ??
          (asNumber(meta.permissionId) != null ? `#${meta.permissionId}` : "?"),
      });
    case "service.delete": {
      // #195: plain (non-force) service deletions get a friendlier summary
      // mirroring user.delete. Falls back to id when nothing readable exists.
      const nameEn = asString(meta.nameEn);
      const nameAr = asString(meta.nameAr);
      const name = lang === "ar" ? nameAr ?? nameEn : nameEn ?? nameAr;
      return name
        ? t("admin.audit.summary.service.delete", { name })
        : t("admin.audit.summary.service.deleteId", {
            id: targetId ?? "?",
          });
    }
    case "service.force_delete": {
      const nameEn = asString(meta.nameEn);
      const nameAr = asString(meta.nameAr);
      const name = lang === "ar" ? nameAr ?? nameEn : nameEn ?? nameAr;
      return t("admin.audit.summary.service.forceDelete", {
        name: name ?? `#${targetId ?? "?"}`,
        orders: unitLabel(t, "order", asNumber(meta.orderCount) ?? 0),
      });
    }
    case "settings.update": {
      const changes = asRecord(meta.changes);
      const totalChanges = Object.keys(changes).length;
      if ("registrationOpen" in changes) {
        const change = asRecord(changes.registrationOpen);
        const opened = change.to === true;
        const otherCount = totalChanges - 1;
        if (otherCount <= 0) {
          return t(
            opened
              ? "admin.audit.summary.settings.registrationOpened"
              : "admin.audit.summary.settings.registrationClosed",
          );
        }
        return t(
          opened
            ? "admin.audit.summary.settings.registrationOpenedWith"
            : "admin.audit.summary.settings.registrationClosedWith",
          { others: unitLabel(t, "change", otherCount) },
        );
      }
      return t("admin.audit.summary.settings.update", {
        changes: unitLabel(t, "change", Math.max(1, totalChanges)),
      });
    }
    case "user.delete": {
      const username = asString(meta.username) ?? `#${targetId ?? "?"}`;
      const displayEn = asString(meta.displayNameEn);
      const displayAr = asString(meta.displayNameAr);
      const displayName = lang === "ar"
        ? displayAr ?? displayEn
        : displayEn ?? displayAr;
      if (displayName) {
        return meta.force
          ? t("admin.audit.summary.user.forceDeleteWithName", {
              username,
              displayName,
            })
          : t("admin.audit.summary.user.deleteWithName", {
              username,
              displayName,
            });
      }
      return meta.force
        ? t("admin.audit.summary.user.forceDelete", { username })
        : t("admin.audit.summary.user.delete", { username });
    }
    default:
      return null;
  }
}
