// Common interfaces for frontend use
import { UserRole, EventStatus, EventCategory, TicketStatus, OrderStatus, PaymentStatus, NotificationType, MerchandiseStatus } from './enums';

// Base interfaces
export interface BaseEntity {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt?: string;
}

// Authentication & Authorization
export interface JwtPayload {
  sub: string;
  username: string;
  email: string;
  role: UserRole;
  iat?: number;
  exp?: number;
}

export interface AuthResult {
  access_token: string;
  user: {
    id: string;
    username: string;
    email: string;
    role: UserRole;
  };
}

// Pagination
export interface PaginationOptions {
  page: number;
  limit: number;
}

export interface PaginatedResult<T> {
  data: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

// User related interfaces
export interface User extends BaseEntity {
  username: string;
  email: string;
  phone?: string;
  role: UserRole;
  isActive: boolean;
  isEmailVerified: boolean;
  isPhoneVerified: boolean;
  lastLoginAt?: string;
  profileImageUrl?: string;
}

export interface UserProfile extends BaseEntity {
  userId: string;
  fullName?: string;
  dateOfBirth?: string;
  gender?: string;
  profileImageUrl?: string;
  address?: string;
  city?: string;
  province?: string;
  postalCode?: string;
  nik?: string; // Optional encrypted NIK for regular users only
  preferences?: Record<string, any>;
}

export interface ArtistProfile extends BaseEntity {
  userId: string;
  stageName: string;
  fullName: string;
  // NIK removed - not required for artists
  bio?: string;
  genre: string[];
  profileImageUrl?: string;
  bannerImageUrl?: string;
  socialMedia: Record<string, string>;
  bankName?: string;
  bankAccountNumber?: string;
  bankAccountName?: string;
  isVerified: boolean;
  verificationDocuments: any[];
  followerCount: number;
}

export interface PromotorProfile extends BaseEntity {
  userId: string;
  companyName: string;
  fullName: string;
  // NIK removed - not required for promotors
  phoneBusiness?: string;
  address?: string;
  city?: string;
  province?: string;
  postalCode?: string;
  bankName?: string;
  bankAccountNumber?: string;
  bankAccountName?: string;
  taxId?: string; // NPWP
  businessLicense?: string; // SIUP/NIB
  isVerified: boolean;
  verificationDocuments: any[];
}

// Event related interfaces
export interface Event extends BaseEntity {
  title: string;
  description: string;
  shortDescription?: string;
  startDate: string;
  endDate: string;
  location: string;
  venueName?: string;
  venueAddress?: string;
  venueCapacity?: number;
  category: EventCategory;
  status: EventStatus;
  imageUrl?: string;
  bannerImageUrl?: string;
  maxCapacity?: number;
  minAge?: number;
  tags: string[];
  organizerId: string;
  isPublic: boolean;
  isFeatured: boolean;
  metadata?: Record<string, any>;
}

export interface EventSchedule extends BaseEntity {
  eventId: string;
  title: string;
  description?: string;
  startTime: string;
  endTime: string;
  location?: string;
  speakers?: string[];
  isBreak: boolean;
  order: number;
}

// Ticket related interfaces
export interface TicketType extends BaseEntity {
  eventId: string;
  name: string;
  description?: string;
  price: number;
  quantityTotal: number;
  quantitySold: number;
  quantityReserved: number;
  saleStartDate?: string;
  saleEndDate?: string;
  benefits: string[];
  hasSeating: boolean;
  status: string;
  metadata?: Record<string, any>;
}

export interface Ticket extends BaseEntity {
  ticketTypeId: string;
  orderId: string;
  ticketNumber: string;
  qrCode: string;
  status: TicketStatus;
  issuedAt?: string;
  usedAt?: string;
  seatNumber?: string;
  holderName?: string;
  holderEmail?: string;
  holderPhone?: string;
  metadata?: Record<string, any>;
}

// Order related interfaces
export interface OrderItem {
  itemType: string;
  itemId: string;
  itemName: string;
  itemDescription?: string;
  unitPrice: number;
  quantity: number;
  discountAmount?: number;
  itemData?: Record<string, any>;
}

export interface Order extends BaseEntity {
  orderNumber: string;
  userId: string;
  status: OrderStatus;
  items: OrderItem[];
  subtotal: number;
  discountAmount: number;
  taxAmount: number;
  shippingAmount: number;
  totalAmount: number;
  currency: string;
  customerInfo: {
    name: string;
    email: string;
    phone?: string;
    address?: string;
  };
  shippingInfo?: {
    address: string;
    city: string;
    postalCode: string;
    country: string;
    method?: string;
    trackingNumber?: string;
  };
  notes?: string;
  metadata?: Record<string, any>;
  expiresAt?: string;
  confirmedAt?: string;
  cancelledAt?: string;
  refundedAt?: string;
  cancellationReason?: string;
  refundReason?: string;
  refundAmount?: number;
  refundInitiatedBy?: string;
  billingAddress?: {
    street: string;
    city: string;
    state?: string;
    postalCode: string;
    country: string;
  };
}

export interface OrderDiscount extends BaseEntity {
  code: string;
  type: string;
  value: number;
  minOrderAmount?: number;
  maxDiscountAmount?: number;
  usageLimit?: number;
  usageCount: number;
  validFrom?: string;
  validUntil?: string;
  status: string;
  description?: string;
  applicableItems?: string[];
  metadata?: Record<string, any>;
}

export interface OrderDiscountUsage extends BaseEntity {
  orderId: string;
  discountId: string;
  discountAmount: number;
  appliedAt: string;
}

export interface OrderShipping extends BaseEntity {
  orderId: string;
  recipientName: string;
  recipientPhone?: string;
  recipientEmail?: string;
  address: string;
  city: string;
  state?: string;
  postalCode: string;
  country: string;
  shippingMethod: string;
  shippingCost: number;
  estimatedDelivery?: string;
  trackingNumber?: string;
  trackingUrl?: string;
  shippingProvider?: string;
  status: string;
  shippedAt?: string;
  deliveredAt?: string;
  notes?: string;
  metadata?: Record<string, any>;
}

export interface OrderStatusHistory extends BaseEntity {
  orderId: string;
  oldStatus: string;
  newStatus: string;
  reason?: string;
  changedBy?: string;
  changedAt: string;
  notes?: string;
  metadata?: Record<string, any>;
}

// Payment related interfaces
export interface Payment extends BaseEntity {
  orderId: string;
  userId: string;
  paymentNumber: string;
  amount: number;
  currency: string;
  method: string;
  provider: string;
  status: PaymentStatus;
  paidAt?: string;
  expiresAt?: string;
  externalPaymentId?: string;
  paymentUrl?: string;
  gatewayResponse?: Record<string, any>;
  gatewayFee?: number;
  processingFee?: number;
  netAmount?: number;
  failureReason?: string;
  failureCode?: string;
  retryCount?: number;
  lastRetryAt?: string;
  customerInfo?: {
    name: string;
    email: string;
    phone?: string;
  };
  billingAddress?: {
    street: string;
    city: string;
    state?: string;
    postalCode: string;
    country: string;
  };
  installmentTerm?: number;
  installmentRate?: number;
  metadata?: Record<string, any>;
}

export interface PaymentRefund extends BaseEntity {
  paymentId: string;
  refundNumber: string;
  refundAmount: number;
  refundReason?: string;
  status: string;
  externalRefundId?: string;
  gatewayResponse?: Record<string, any>;
  processedAt?: string;
  failureReason?: string;
  metadata?: Record<string, any>;
}

export interface PaymentWebhook extends BaseEntity {
  paymentId: string;
  webhookSource: string;
  webhookEvent: string;
  requestMethod: string;
  requestHeaders?: Record<string, any>;
  requestBody?: Record<string, any>;
  responseStatus?: number;
  responseBody?: Record<string, any>;
  status: string;
  processedAt?: string;
  errorMessage?: string;
  retryCount?: number;
  metadata?: Record<string, any>;
}

export interface PaymentInstallment extends BaseEntity {
  paymentId: string;
  installmentNumber: number;
  installmentAmount: number;
  dueDate: string;
  status: string;
  paidAt?: string;
  lateFee?: number;
  metadata?: Record<string, any>;
}

export interface PaymentDispute extends BaseEntity {
  paymentId: string;
  disputeType: string;
  disputeReason: string;
  disputeAmount: number;
  status: string;
  externalDisputeId?: string;
  disputeDate: string;
  evidence?: Record<string, any>;
  merchantResponse?: string;
  resolvedAt?: string;
  resolution?: string;
  metadata?: Record<string, any>;
}

export interface PaymentMethodConfig extends BaseEntity {
  methodName: string;
  provider: string;
  isActive: boolean;
  displayName: string;
  description?: string;
  logoUrl?: string;
  fixedFee?: number;
  percentageFee?: number;
  minAmount?: number;
  maxAmount?: number;
  supportedCurrencies?: string[];
  processingTime?: string;
  providerConfig?: Record<string, any>;
  metadata?: Record<string, any>;
}

// Notification related interfaces
export interface Notification extends BaseEntity {
  recipientId: string;
  type: NotificationType;
  title: string;
  message: string;
  data?: Record<string, any>;
  isRead: boolean;
  readAt?: string;
  sentAt?: string;
  scheduledAt?: string;
  metadata?: Record<string, any>;
}

// Merchandise related interfaces
export interface Merchandise extends BaseEntity {
  name: string;
  description?: string;
  shortDescription?: string;
  category: string;
  subcategory?: string;
  tags: string[];
  ownerType: string;
  ownerId: string;
  eventId?: string;
  basePrice: number;
  salePrice?: number;
  costPrice?: number;
  trackInventory: boolean;
  totalStock: number;
  reservedStock: number;
  availableStock: number;
  status: MerchandiseStatus;
  images: string[];
  weight?: number;
  dimensions?: {
    length: number;
    width: number;
    height: number;
  };
  metadata?: Record<string, any>;
}

export interface MerchandiseVariant extends BaseEntity {
  merchandiseId: string;
  name: string;
  sku?: string;
  price?: number;
  stock: number;
  reservedStock: number;
  attributes: Record<string, string>;
  images: string[];
  isActive: boolean;
}

export interface MerchandiseOrder extends BaseEntity {
  orderNumber: string;
  userId: string;
  status: string;
  subtotal: number;
  discountAmount: number;
  taxAmount: number;
  shippingAmount: number;
  totalAmount: number;
  currency: string;
  customerInfo: {
    name: string;
    email: string;
    phone?: string;
  };
  shippingAddress: {
    street: string;
    city: string;
    state?: string;
    postalCode: string;
    country: string;
  };
  billingAddress?: {
    street: string;
    city: string;
    state?: string;
    postalCode: string;
    country: string;
  };
  paymentMethod?: string;
  paymentStatus?: string;
  shippingMethod?: string;
  trackingNumber?: string;
  estimatedDelivery?: string;
  shippedAt?: string;
  deliveredAt?: string;
  cancelledAt?: string;
  cancellationReason?: string;
  refundedAt?: string;
  refundAmount?: number;
  notes?: string;
  metadata?: Record<string, any>;
}

export interface MerchandiseOrderItem extends BaseEntity {
  orderId: string;
  merchandiseId: string;
  variantId?: string;
  merchandiseName: string;
  variantName?: string;
  unitPrice: number;
  quantity: number;
  discountAmount?: number;
  totalPrice: number;
  itemData?: Record<string, any>;
}

export interface MerchandiseCollection extends BaseEntity {
  name: string;
  description?: string;
  slug: string;
  isActive: boolean;
  sortOrder?: number;
  imageUrl?: string;
  metadata?: Record<string, any>;
}

export interface MerchandiseCollectionItem extends BaseEntity {
  collectionId: string;
  merchandiseId: string;
  sortOrder?: number;
}

// API Response types
export interface ApiResponse<T = any> {
  success: boolean;
  data?: T;
  message?: string;
  errors?: string[];
}

export interface ApiError {
  message: string;
  statusCode: number;
  error?: string;
  timestamp: string;
  path: string;
}

// Query and Filter types
export interface BaseQuery {
  page?: number;
  limit?: number;
  search?: string;
  sortBy?: string;
  sortOrder?: 'ASC' | 'DESC';
}

export interface EventQuery extends BaseQuery {
  category?: EventCategory;
  status?: EventStatus;
  startDate?: string;
  endDate?: string;
  location?: string;
  organizerId?: string;
  isFeatured?: boolean;
}

export interface OrderQuery extends BaseQuery {
  status?: OrderStatus;
  userId?: string;
  startDate?: string;
  endDate?: string;
}

export interface MerchandiseQuery extends BaseQuery {
  category?: string;
  status?: MerchandiseStatus;
  ownerId?: string;
  eventId?: string;
  minPrice?: number;
  maxPrice?: number;
}

// Settings System Interfaces
export interface SystemSetting extends BaseEntity {
  category: string;
  key: string;
  value: any;
  dataType: string;
  description?: string;
  isEncrypted: boolean;
  requiresRestart: boolean;
  isActive: boolean;
  environment: string;
  validation?: {
    required?: boolean;
    min?: number;
    max?: number;
    pattern?: string;
    enum?: string[];
    customValidator?: string;
  };
  metadata?: {
    group?: string;
    order?: number;
    tags?: string[];
    icon?: string;
    helpText?: string;
    warningMessage?: string;
  };
  defaultValue?: string;
  isReadOnly: boolean;
  isSystemGenerated: boolean;
  createdBy?: string;
  updatedBy?: string;
}

export interface SettingsHistory extends BaseEntity {
  settingId: string;
  settingKey: string;
  settingCategory: string;
  oldValue?: any;
  newValue: any;
  changeType: string;
  source: string;
  changeReason?: string;
  notes?: string;
  changedBy: string;
  ipAddress?: string;
  userAgent?: string;
  metadata?: {
    requestId?: string;
    sessionId?: string;
    apiVersion?: string;
    rollbackId?: string;
    batchId?: string;
  };
  changedAt: string;
}

export interface FeatureFlag extends BaseEntity {
  name: string;
  displayName: string;
  description?: string;
  type: string;
  status: string;
  scope: string;
  isEnabled: boolean;
  rolloutPercentage: number;
  targetCriteria?: {
    userIds?: string[];
    roles?: string[];
    countries?: string[];
    cities?: string[];
    deviceTypes?: string[];
    browserTypes?: string[];
    ipRanges?: string[];
    userSegments?: string[];
    customAttributes?: Record<string, any>;
  };
  environment: string;
  startDate?: string;
  endDate?: string;
  configuration?: {
    fallbackValue?: any;
    dependencies?: string[];
    conflictsWith?: string[];
    variants?: Array<{
      name: string;
      value: any;
      percentage: number;
    }>;
  };
  metadata?: {
    category?: string;
    tags?: string[];
    owner?: string;
    jiraTicket?: string;
    documentation?: string;
    priority?: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
  };
  metrics?: {
    evaluations?: number;
    trueEvaluations?: number;
    falseEvaluations?: number;
    lastEvaluated?: string;
    errors?: number;
  };
  isPermanent: boolean;
  isArchived: boolean;
  createdBy?: string;
  updatedBy?: string;
}

export interface EmailTemplate extends BaseEntity {
  templateKey: string;
  name: string;
  description?: string;
  type: string;
  status: string;
  subject: string;
  htmlContent: string;
  textContent?: string;
  format: string;
  variables?: Array<{
    name: string;
    type: 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object';
    required: boolean;
    defaultValue?: any;
    description?: string;
    validation?: {
      pattern?: string;
      min?: number;
      max?: number;
      enum?: string[];
    };
  }>;
  sampleData?: Record<string, any>;
  priority: string;
  isDefault: boolean;
  isActive: boolean;
  fromName?: string;
  fromEmail?: string;
  replyTo?: string;
  categories?: string[];
  tags?: string[];
  settings?: {
    trackOpens?: boolean;
    trackClicks?: boolean;
    unsubscribeLink?: boolean;
    customHeaders?: Record<string, string>;
    attachments?: Array<{
      name: string;
      url: string;
      contentType: string;
    }>;
  };
  localization?: Record<string, {
    subject: string;
    htmlContent: string;
    textContent?: string;
  }>;
  version: number;
  parentTemplateId?: string;
  metadata?: {
    designer?: string;
    designTool?: string;
    thumbnailUrl?: string;
    previewUrl?: string;
    testData?: Record<string, any>;
  };
  lastUsed?: string;
  usageCount: number;
  createdBy?: string;
  updatedBy?: string;
}