import type { Order, OrderItem, OrderItemInput, OrderState, OrderView } from './order.js';

export interface OrderRepository {
  create(input: {
    userId: string;
    idempotencyKey: string | null;
    items: OrderItemInput[];
    totals: { subtotalCents: number; discountCents: number; taxCents: number; totalCents: number };
  }): Promise<OrderView>;
  findAll(): Promise<OrderView[]>;
  search?(filters: {
    state?: string;
    q?: string;
    limit: number;
    offset: number;
  }): Promise<{ items: OrderView[]; total: number }>;
  findById(id: string): Promise<OrderView | undefined>;
  findByIdAndUserId(id: string, userId: string): Promise<OrderView | undefined>;
  updateState(id: string, state: OrderState, trackingNumber?: string, courier?: string): Promise<OrderView | undefined>;
  /** Reemplaza los artículos y totales del pedido (edición admin). */
  replaceItems?(
    id: string,
    items: OrderItemInput[],
    totals: { subtotalCents: number; discountCents: number; taxCents: number; totalCents: number },
  ): Promise<OrderView | undefined>;
}

export interface OrderEventPublisher {
  emit(event: OrderEvent): Promise<void>;
}

export type OrderEvent =
  | { type: 'OrderCreated'; orderId: string; userId: string }
  | { type: 'OrderPaid'; orderId: string; userId: string }
  | { type: 'OrderCancelled'; orderId: string; userId: string };

export interface OrderServicePort {
  create(input: CreateOrderCommand): Promise<OrderView>;
  listOrders(): Promise<OrderView[]>;
  searchOrders?(filters: {
    state?: string;
    q?: string;
    limit: number;
    offset: number;
  }): Promise<{ items: OrderView[]; total: number }>;
  transition(id: string, next: OrderState, userId: string): Promise<OrderView>;
  transitionAdmin(id: string, next: OrderState, trackingNumber?: string, courier?: string): Promise<OrderView>;
  getOrder(id: string, userId: string): Promise<OrderView | undefined>;
  getOrderAdmin(id: string): Promise<OrderView | undefined>;
}

export interface CreateOrderCommand {
  userId: string;
  idempotencyKey?: string | null;
  items: OrderItemInput[];
  totals: { subtotalCents: number; discountCents: number; taxCents: number; totalCents: number };
}

export type { Order, OrderItem, OrderItemInput, OrderState, OrderView };
