import { DomainError } from "../../shared/errors.ts";
import { authorize, Permissions, type StaffPrincipal } from "../identity/permissions.ts";
import { assertSellerMaySell, type KycSubmission } from "../kyc/seller-verification.ts";
import type { Listing } from "../marketplace/listings.ts";

export interface ModerationDecision {
  readonly listing: Listing;
  readonly event: {
    readonly eventKey: string;
    readonly listingId: string;
    readonly actorStaffId: string;
    readonly decision: "approved" | "rejected";
    readonly reason?: string;
    readonly occurredAt: Date;
  };
}

export function moderateListing(
  listing: Listing,
  decision: "approved" | "rejected",
  principal: StaffPrincipal | null,
  latestSellerKyc: KycSubmission | null,
  now: Date,
  reason?: string,
): ModerationDecision {
  authorize(principal, Permissions.ListingsModerate);
  if (listing.status !== "pending_review") throw new DomainError("INVALID_LISTING_TRANSITION", "Only a pending listing can be moderated.");
  if (decision === "approved") assertSellerMaySell(latestSellerKyc);
  if (decision === "rejected" && !reason?.trim()) throw new DomainError("REJECTION_REASON_REQUIRED", "A rejection reason is required.");
  const next: Listing = { ...listing, status: decision === "approved" ? "active" : "rejected", version: listing.version + 1 };
  return {
    listing: next,
    event: {
      eventKey: `${listing.id}:moderation:${listing.version + 1}`,
      listingId: listing.id,
      actorStaffId: principal!.staffId,
      decision,
      ...(reason?.trim() ? { reason: reason.trim() } : {}),
      occurredAt: now,
    },
  };
}

export function setCatalogAvailability(principal: StaffPrincipal | null, enabled: boolean): boolean {
  authorize(principal, Permissions.ConfigurationManage);
  return enabled;
}
