/**
 * rCart Automerge document schemas.
 *
 * Two document types:
 * - Catalog: one doc per space holding all catalog entries.
 *   DocId: {space}:cart:catalog
 * - Orders: one doc per order (server-validated via Intent/Claim).
 *   DocId: {space}:cart:orders:{orderId}
 */

import type { DocSchema } from '../../shared/local-first/document';

// ── Document types ──

export interface CatalogEntry {
	id: string;
	artifactId: string;
	artifact: unknown;
	title: string;
	productType: string | null;
	requiredCapabilities: string[];
	substrates: string[];
	creatorId: string | null;
	sourceSpace: string | null;
	tags: string[];
	status: string;
	createdAt: number;
	updatedAt: number;
}

export interface CatalogDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	items: Record<string, CatalogEntry>;
}

export interface OrderMeta {
	id: string;
	catalogEntryId: string;
	artifactId: string;
	buyerId: string | null;
	buyerLocation: string | null;
	buyerContact: string | null;
	providerId: string | null;
	providerName: string | null;
	providerDistanceKm: number | null;
	quantity: number;
	productionCost: number | null;
	creatorPayout: number | null;
	communityPayout: number | null;
	totalPrice: number | null;
	currency: string;
	status: string;
	paymentMethod: string | null;
	paymentTx: string | null;
	paymentNetwork: string | null;
	createdAt: number;
	paidAt: number;
	acceptedAt: number;
	completedAt: number;
	updatedAt: number;
}

export interface OrderDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	order: OrderMeta;
}

// ── Schema registration ──

export const catalogSchema: DocSchema<CatalogDoc> = {
	module: 'cart',
	collection: 'catalog',
	version: 1,
	init: (): CatalogDoc => ({
		meta: {
			module: 'cart',
			collection: 'catalog',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		items: {},
	}),
};

export const orderSchema: DocSchema<OrderDoc> = {
	module: 'cart',
	collection: 'orders',
	version: 1,
	init: (): OrderDoc => ({
		meta: {
			module: 'cart',
			collection: 'orders',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		order: {
			id: '',
			catalogEntryId: '',
			artifactId: '',
			buyerId: null,
			buyerLocation: null,
			buyerContact: null,
			providerId: null,
			providerName: null,
			providerDistanceKm: null,
			quantity: 1,
			productionCost: null,
			creatorPayout: null,
			communityPayout: null,
			totalPrice: null,
			currency: 'USD',
			status: 'pending',
			paymentMethod: null,
			paymentTx: null,
			paymentNetwork: null,
			createdAt: Date.now(),
			paidAt: 0,
			acceptedAt: 0,
			completedAt: 0,
			updatedAt: Date.now(),
		},
	}),
};

// ── Shopping Cart types ──

export type CartStatus = 'OPEN' | 'FUNDING' | 'FUNDED' | 'CHECKING_OUT' | 'ORDERED' | 'CLOSED';

export interface CartItemVendor {
	name: string;
	domain: string;
	platform: string | null; // 'amazon' | 'shopify' | 'etsy' | null
}

export interface CartItem {
	name: string;
	price: number | null;
	currency: string;
	quantity: number;
	sourceUrl: string;
	imageUrl: string | null;
	description: string | null;
	vendor: CartItemVendor;
	addedBy: string | null; // DID
	addedAt: number;
	sku: string | null;
}

export interface CartContribution {
	userId: string | null;
	username: string;
	amount: number;
	currency: string;
	paymentMethod: string; // 'MANUAL' for MVP
	status: string; // 'pending' | 'confirmed'
	txHash: string | null;
	createdAt: number;
	updatedAt: number;
}

export interface CartEvent {
	type: string; // 'item_added' | 'item_removed' | 'contribution' | 'status_change'
	actor: string;
	detail: string;
	timestamp: number;
}

export interface ShoppingCartDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	cart: {
		id: string;
		name: string;
		description: string;
		status: CartStatus;
		createdBy: string | null;
		recipientAddress: string | null;
		targetAmount: number;
		fundedAmount: number;
		currency: string;
		createdAt: number;
		updatedAt: number;
	};
	items: Record<string, CartItem>;
	contributions: Record<string, CartContribution>;
	events: CartEvent[];
}

export interface ShoppingCartIndexEntry {
	name: string;
	status: CartStatus;
	itemCount: number;
	totalAmount: number;
	fundedAmount: number;
	currency: string;
	createdAt: number;
	updatedAt: number;
}

export interface ShoppingCartIndexDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	carts: Record<string, ShoppingCartIndexEntry>;
}

// ── Shopping Cart schema registration ──

export const shoppingCartSchema: DocSchema<ShoppingCartDoc> = {
	module: 'cart',
	collection: 'shopping',
	version: 1,
	init: (): ShoppingCartDoc => ({
		meta: {
			module: 'cart',
			collection: 'shopping',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		cart: {
			id: '',
			name: '',
			description: '',
			status: 'OPEN',
			createdBy: null,
			recipientAddress: null,
			targetAmount: 0,
			fundedAmount: 0,
			currency: 'USD',
			createdAt: Date.now(),
			updatedAt: Date.now(),
		},
		items: {},
		contributions: {},
		events: [],
	}),
};

export const shoppingCartIndexSchema: DocSchema<ShoppingCartIndexDoc> = {
	module: 'cart',
	collection: 'shopping-index',
	version: 1,
	init: (): ShoppingCartIndexDoc => ({
		meta: {
			module: 'cart',
			collection: 'shopping-index',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		carts: {},
	}),
};

// ── Payment Request types ──

/** Individual payment record in a subscription's history. */
export interface PaymentRecord {
	txHash: string | null;
	transakOrderId: string | null;
	paymentMethod: 'transak' | 'wallet' | 'encryptid' | null;
	payerIdentity: string | null;
	payerEmail: string | null;
	amount: string;
	paidAt: number;
}

export interface PaymentRequestMeta {
	id: string;
	description: string;
	amount: string;
	amountEditable: boolean;
	token: string;
	chainId: number;
	recipientAddress: string;
	fiatAmount: string | null;
	fiatCurrency: string;
	creatorDid: string;
	creatorUsername: string;
	status: 'pending' | 'paid' | 'confirmed' | 'expired' | 'cancelled' | 'filled';
	paymentMethod: 'transak' | 'wallet' | 'encryptid' | null;
	txHash: string | null;
	payerIdentity: string | null;
	transakOrderId: string | null;
	// Payment type: one-time, recurring, or payer's choice
	paymentType: 'single' | 'subscription' | 'payer_choice';
	// Inventory: max number of payments (0 = unlimited)
	maxPayments: number;
	// How many have been paid
	paymentCount: number;
	// Which payment methods are enabled for payers
	enabledMethods: {
		card: boolean;
		wallet: boolean;
		encryptid: boolean;
	};
	// Subscription interval (for recurring payments)
	interval: 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | null;
	// Next payment due date (epoch ms, 0 = not scheduled)
	nextDueAt: number;
	// Subscriber email (for payment reminders)
	subscriberEmail: string | null;
	// Linked shopping cart (for contribute-pay flow)
	linkedCartId: string | null;
	// Payment history (all individual payments)
	paymentHistory: PaymentRecord[];
	createdAt: number;
	updatedAt: number;
	paidAt: number;
	expiresAt: number;
}

export interface PaymentRequestDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	payment: PaymentRequestMeta;
}

export const paymentRequestSchema: DocSchema<PaymentRequestDoc> = {
	module: 'cart',
	collection: 'payments',
	version: 1,
	init: (): PaymentRequestDoc => ({
		meta: {
			module: 'cart',
			collection: 'payments',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		payment: {
			id: '',
			description: '',
			amount: '0',
			amountEditable: false,
			token: 'USDC',
			chainId: 8453,
			recipientAddress: '',
			fiatAmount: null,
			fiatCurrency: 'USD',
			creatorDid: '',
			creatorUsername: '',
			status: 'pending',
			paymentMethod: null,
			txHash: null,
			payerIdentity: null,
			transakOrderId: null,
			paymentType: 'single',
			maxPayments: 0,
			paymentCount: 0,
			enabledMethods: { card: true, wallet: true, encryptid: true },
			interval: null,
			nextDueAt: 0,
			subscriberEmail: null,
			linkedCartId: null,
			paymentHistory: [],
			createdAt: Date.now(),
			updatedAt: Date.now(),
			paidAt: 0,
			expiresAt: 0,
		},
	}),
};

// ── Group Buy types ──

export type GroupBuyStatus = 'OPEN' | 'LOCKED' | 'ORDERED' | 'CANCELLED';

export interface GroupBuyTier {
	min_qty: number;
	per_unit: number;
	currency: string;
}

export interface GroupBuyPledge {
	id: string;
	buyerId: string | null;
	displayName: string;
	quantity: number;
	pledgedAt: number;
}

export interface GroupBuyDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	buy: {
		id: string;
		catalogEntryId: string;
		artifactId: string;
		title: string;
		productType: string | null;
		imageUrl: string | null;
		description: string;
		tiers: GroupBuyTier[];
		status: GroupBuyStatus;
		totalPledged: number;
		createdBy: string | null;
		createdAt: number;
		updatedAt: number;
		closesAt: number;
	};
	pledges: Record<string, GroupBuyPledge>;
}

export const groupBuySchema: DocSchema<GroupBuyDoc> = {
	module: 'cart',
	collection: 'group-buys',
	version: 1,
	init: (): GroupBuyDoc => ({
		meta: {
			module: 'cart',
			collection: 'group-buys',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		buy: {
			id: '',
			catalogEntryId: '',
			artifactId: '',
			title: '',
			productType: null,
			imageUrl: null,
			description: '',
			tiers: [],
			status: 'OPEN',
			totalPledged: 0,
			createdBy: null,
			createdAt: Date.now(),
			updatedAt: Date.now(),
			closesAt: 0,
		},
		pledges: {},
	}),
};

// ── Helpers ──

export function catalogDocId(space: string) {
	return `${space}:cart:catalog` as const;
}

export function orderDocId(space: string, orderId: string) {
	return `${space}:cart:orders:${orderId}` as const;
}

export function shoppingCartDocId(space: string, cartId: string) {
	return `${space}:cart:shopping:${cartId}` as const;
}

export function shoppingCartIndexDocId(space: string) {
	return `${space}:cart:shopping-index` as const;
}

export function paymentRequestDocId(space: string, paymentId: string) {
	return `${space}:cart:payments:${paymentId}` as const;
}

export function groupBuyDocId(space: string, buyId: string) {
	return `${space}:cart:group-buys:${buyId}` as const;
}
