/**
 * Generic Marketplace Module Types
 *
 * Product-agnostic marketplace for user-created templates across all ByteLyst apps.
 * Every document carries a productId for multi-product support.
 */

import { z } from 'zod';

// ─────────────────────────────────────────────────────────────────────────────
// Listing Types
// ─────────────────────────────────────────────────────────────────────────────

export const CERTIFICATION_STATUSES = [
  'draft',
  'submitted',
  'in_review',
  'approved',
  'rejected',
  'suspended',
] as const;

export const PRICING_MODELS = ['free', 'paid', 'freemium'] as const;

export const VISIBILITY_LEVELS = ['private', 'unlisted', 'public'] as const;

export type CertificationStatus = (typeof CERTIFICATION_STATUSES)[number];
export type PricingModel = (typeof PRICING_MODELS)[number];
export type Visibility = (typeof VISIBILITY_LEVELS)[number];

export interface MarketplaceListingDoc {
  id: string; // lst_<uuid>
  productId: string;
  templateType: string;

  // Author
  authorId: string;
  authorName: string;
  authorAvatarUrl: string | null;

  // Content
  title: string;
  shortDescription: string;
  description: string;
  tags: string[];
  category: string;
  screenshots: string[];
  previewUrl: string | null;

  // Template payload (product-specific JSON)
  payload: Record<string, unknown>;
  payloadVersion: string;

  // Pricing
  pricingModel: PricingModel;
  priceInCents: number;
  currency: string;

  // Certification
  certificationStatus: CertificationStatus;
  certificationNotes: string | null;
  certifiedAt: string | null;
  certifiedBy: string | null;

  // Stats (denormalized for fast reads)
  installCount: number;
  reviewCount: number;
  averageRating: number;
  voteCount: number;

  // Versioning
  version: string;
  previousVersionId: string | null;

  // Metadata
  visibility: Visibility;
  featured: boolean;
  createdAt: string;
  updatedAt: string;
  publishedAt: string | null;
}

export const CreateListingSchema = z.object({
  productId: z.string().min(1).optional(),
  templateType: z.string().min(1).max(50),
  title: z.string().min(1).max(200),
  shortDescription: z.string().min(1).max(200),
  description: z.string().min(1).max(10000),
  tags: z.array(z.string()).max(10).default([]),
  category: z.string().min(1).max(50),
  screenshots: z.array(z.string().url()).max(10).default([]),
  previewUrl: z.string().url().nullable().default(null),
  payload: z.record(z.unknown()),
  payloadVersion: z.string().default('1.0'),
  pricingModel: z.enum(PRICING_MODELS).default('free'),
  priceInCents: z.number().min(0).default(0),
  currency: z.string().default('usd'),
  visibility: z.enum(VISIBILITY_LEVELS).default('private'),
  version: z.string().default('1.0.0'),
});

export const UpdateListingSchema = z.object({
  title: z.string().min(1).max(200).optional(),
  shortDescription: z.string().min(1).max(200).optional(),
  description: z.string().min(1).max(10000).optional(),
  tags: z.array(z.string()).max(10).optional(),
  category: z.string().min(1).max(50).optional(),
  screenshots: z.array(z.string().url()).max(10).optional(),
  previewUrl: z.string().url().nullable().optional(),
  payload: z.record(z.unknown()).optional(),
  payloadVersion: z.string().optional(),
  pricingModel: z.enum(PRICING_MODELS).optional(),
  priceInCents: z.number().min(0).optional(),
  visibility: z.enum(VISIBILITY_LEVELS).optional(),
  version: z.string().optional(),
});

export const SubmitForCertificationSchema = z.object({
  notes: z.string().max(1000).optional(),
});

export const CertificationActionSchema = z.object({
  notes: z.string().max(1000).optional(),
  automatedChecks: z
    .object({
      promptSafety: z.enum(['pass', 'fail', 'warn']),
      contentPolicy: z.enum(['pass', 'fail', 'warn']),
      payloadValid: z.boolean(),
      screenshotCount: z.number().min(0),
    })
    .optional(),
});

export const ListListingsQuerySchema = z.object({
  productId: z.string().optional(),
  templateType: z.string().optional(),
  category: z.string().optional(),
  tags: z.string().optional(), // comma-separated
  pricingModel: z.enum(PRICING_MODELS).optional(),
  minRating: z.coerce.number().min(0).max(5).optional(),
  sortBy: z.enum(['installCount', 'rating', 'newest', 'trending', 'createdAt']).default('createdAt'),
  sortOrder: z.enum(['asc', 'desc']).default('desc'),
  q: z.string().optional(),
  limit: z.coerce.number().min(1).max(100).default(20),
  offset: z.coerce.number().min(0).default(0),
});

export type CreateListingInput = z.infer<typeof CreateListingSchema>;
export type UpdateListingInput = z.infer<typeof UpdateListingSchema>;
export type SubmitForCertificationInput = z.infer<typeof SubmitForCertificationSchema>;
export type CertificationActionInput = z.infer<typeof CertificationActionSchema>;
export type ListListingsQuery = z.infer<typeof ListListingsQuerySchema>;

// ─────────────────────────────────────────────────────────────────────────────
// Review Types
// ─────────────────────────────────────────────────────────────────────────────

export interface MarketplaceReviewDoc {
  id: string; // rev_<uuid>
  listingId: string;
  productId: string;
  authorId: string;
  authorName: string;
  rating: number; // 1-5 stars
  title: string;
  body: string;
  helpful: number;
  verified: boolean; // Author actually installed the template
  createdAt: string;
  updatedAt: string;
}

export const CreateReviewSchema = z.object({
  rating: z.number().min(1).max(5),
  title: z.string().min(1).max(200),
  body: z.string().min(1).max(2000),
});

export const UpdateReviewSchema = z.object({
  rating: z.number().min(1).max(5).optional(),
  title: z.string().min(1).max(200).optional(),
  body: z.string().min(1).max(2000).optional(),
});

export const ListReviewsQuerySchema = z.object({
  sortBy: z.enum(['newest', 'helpful', 'rating']).default('newest'),
  sortOrder: z.enum(['asc', 'desc']).default('desc'),
  verifiedOnly: z.coerce.boolean().default(false),
  limit: z.coerce.number().min(1).max(100).default(20),
  offset: z.coerce.number().min(0).default(0),
});

export type CreateReviewInput = z.infer<typeof CreateReviewSchema>;
export type UpdateReviewInput = z.infer<typeof UpdateReviewSchema>;
export type ListReviewsQuery = z.infer<typeof ListReviewsQuerySchema>;

// ─────────────────────────────────────────────────────────────────────────────
// Install Types
// ─────────────────────────────────────────────────────────────────────────────

export interface MarketplaceInstallDoc {
  id: string; // inst_<uuid>
  listingId: string;
  productId: string;
  userId: string;
  version: string;
  installedAt: string;
  uninstalledAt: string | null;
}

export const ListInstallsQuerySchema = z.object({
  productId: z.string().optional(),
  limit: z.coerce.number().min(1).max(100).default(20),
  offset: z.coerce.number().min(0).default(0),
});

export type ListInstallsQuery = z.infer<typeof ListInstallsQuerySchema>;

// ─────────────────────────────────────────────────────────────────────────────
// Certification Audit Types
// ─────────────────────────────────────────────────────────────────────────────

export const CERTIFICATION_ACTIONS = ['submitted', 'approved', 'rejected', 'suspended', 'resubmitted'] as const;
export type CertificationAction = (typeof CERTIFICATION_ACTIONS)[number];

export interface MarketplaceCertificationDoc {
  id: string; // cert_<uuid>
  listingId: string;
  productId: string;
  action: CertificationAction;
  performedBy: string;
  notes: string;
  automatedChecks: {
    promptSafety: 'pass' | 'fail' | 'warn';
    contentPolicy: 'pass' | 'fail' | 'warn';
    payloadValid: boolean;
    screenshotCount: number;
  } | null;
  createdAt: string;
}

// ─────────────────────────────────────────────────────────────────────────────
// Report Types
// ─────────────────────────────────────────────────────────────────────────────

export const REPORT_REASONS = [
  'spam',
  'harmful',
  'misleading',
  'copyright',
  'inappropriate',
  'other',
] as const;
export type ReportReason = (typeof REPORT_REASONS)[number];

export const REPORT_STATUSES = ['open', 'resolved', 'dismissed'] as const;
export type ReportStatus = (typeof REPORT_STATUSES)[number];

export interface MarketplaceReportDoc {
  id: string; // rpt_<uuid>
  listingId: string;
  productId: string;
  reporterId: string;
  reason: ReportReason;
  details: string;
  status: ReportStatus;
  resolvedBy: string | null;
  resolutionNotes: string | null;
  createdAt: string;
  resolvedAt: string | null;
}

export const CreateReportSchema = z.object({
  reason: z.enum(REPORT_REASONS),
  details: z.string().min(1).max(2000),
});

export const ResolveReportSchema = z.object({
  status: z.enum(['resolved', 'dismissed']),
  resolutionNotes: z.string().max(2000).optional(),
});

export const ListReportsQuerySchema = z.object({
  productId: z.string().optional(),
  status: z.enum(REPORT_STATUSES).optional(),
  limit: z.coerce.number().min(1).max(100).default(20),
  offset: z.coerce.number().min(0).default(0),
});

export type CreateReportInput = z.infer<typeof CreateReportSchema>;
export type ResolveReportInput = z.infer<typeof ResolveReportSchema>;
export type ListReportsQuery = z.infer<typeof ListReportsQuerySchema>;

// ─────────────────────────────────────────────────────────────────────────────
// Vote Types (to prevent duplicate voting)
// ─────────────────────────────────────────────────────────────────────────────

export interface MarketplaceVoteDoc {
  id: string; // vote_<uuid>
  listingId: string;
  productId: string;
  userId: string;
  createdAt: string;
}

export type ListMyReportsQuery = {
  productId?: string;
};
