import { z } from 'zod';
import { ApiResponseSchema } from '#contracts/shared';

// ---------------------------------------------------------------------------
// Enums
// ---------------------------------------------------------------------------

export const NotificationTypeEnum = z.enum([
	'order_created',
	'payment_success',
	'payment_failed',
	'order_shipped',
	'order_delivered',
	'system_alert',
	'promotion',
	'chat_message',
	'security_alert',
	'account_update',
]);

export const NotificationChannelEnum = z.enum(['in_app', 'push', 'email', 'sms', 'zalo']);

export const NotificationPlatformEnum = z.enum(['web', 'ios', 'android', 'zalo_mini_app']);

// ---------------------------------------------------------------------------
// Entity schema
// ---------------------------------------------------------------------------

export const NotificationSchema = z
	.object({
		id: z.uuid(),
		title: z.string(),
		body: z.string().nullable(),
		type: NotificationTypeEnum,
		data: z.record(z.string(), z.unknown()).nullable(),
		tenant_id: z.uuid().nullable(),
		scheduled_at: z.iso.datetime().nullable(),
		priority: z.number().int().nullable(),
		created_by: z.uuid().nullable(),
		campaign_id: z.uuid().nullable(),
		template_id: z.uuid().nullable(),
		external_key: z.string().nullable(),
		dedupe_key: z.string().nullable(),
		created_at: z.iso.datetime(),
		updated_at: z.iso.datetime().nullable(),
		// Receipt fields (from NotificationReceipt)
		user_id: z.uuid(),
		channel: NotificationChannelEnum,
		read_at: z.iso.datetime().nullable(),
		deleted_at: z.iso.datetime().nullable(),
		archived_at: z.iso.datetime().nullable(),
	})
	.openapi('Notification');

export type Notification = z.infer<typeof NotificationSchema>;

// ---------------------------------------------------------------------------
// Request schemas
// ---------------------------------------------------------------------------

export const NotificationMutateBodySchema = z
	.object({
		title: z.string().min(1).max(255).openapi({ example: 'Order Shipped' }),
		body: z
			.string()
			.min(1)
			.max(2000)
			.openapi({ example: 'Your order #12345 has been shipped and will arrive in 2-3 business days.' }),
		user_id: z
			.union([z.uuid(), z.array(z.uuid()).min(1)])
			.nullable()
			.optional()
			.openapi({ example: '550e8400-e29b-41d4-a716-446655440000' }),
		type: NotificationTypeEnum.default('system_alert').openapi({ example: 'order_shipped' }),
		channel: NotificationChannelEnum.default('in_app').openapi({ example: 'push' }),
		platform: NotificationPlatformEnum.nullable().optional().openapi({ example: 'ios' }),
		data: z
			.record(z.string(), z.unknown())
			.nullable()
			.optional()
			.openapi({
				example: {
					order_id: '12345',
					tracking_number: 'TN123456789',
				},
			}),
		tenant_id: z.uuid().nullable().optional().openapi({ example: '550e8400-e29b-41d4-a716-446655440001' }),
		scheduled_at: z.iso.datetime().nullable().optional().openapi({ example: '2024-01-15T10:00:00Z' }),
		priority: z.number().int().nullable().optional().openapi({ example: 1 }),
	})
	.openapi('NotificationMutateBody');

export type NotificationMutateBody = z.infer<typeof NotificationMutateBodySchema>;

// ---------------------------------------------------------------------------
// Paginated list
// ---------------------------------------------------------------------------

export const NotificationListDataSchema = z
	.object({
		count: z.number().int(),
		rows: z.array(NotificationSchema),
		page: z.number().int(),
		pageSize: z.number().int(),
		unread_count: z.number().int(),
	})
	.openapi('NotificationListData');

// ---------------------------------------------------------------------------
// Full response schemas (envelope + data)
// ---------------------------------------------------------------------------

export const NotificationResponseSchema = ApiResponseSchema(NotificationSchema).openapi('NotificationResponse');
export type NotificationResponse = z.infer<typeof NotificationResponseSchema>;

export const NotificationListResponseSchema =
	ApiResponseSchema(NotificationListDataSchema).openapi('NotificationListResponse');
export type NotificationListResponse = z.infer<typeof NotificationListResponseSchema>;

// ---------------------------------------------------------------------------
// Notification preference schema
// ---------------------------------------------------------------------------

export const NotificationPreferenceSchema = z
	.object({
		id: z.uuid(),
		user_id: z.uuid(),
		notification_type: NotificationTypeEnum,
		channel: NotificationChannelEnum,
		is_enabled: z.boolean().default(true),
		quiet_hours_start: z.string().nullable(),
		quiet_hours_end: z.string().nullable(),
		created_at: z.iso.datetime(),
		updated_at: z.iso.datetime().nullable(),
	})
	.openapi('NotificationPreference');

export type NotificationPreference = z.infer<typeof NotificationPreferenceSchema>;

export const NotificationPreferenceUpdateSchema = z
	.array(
		z.object({
			notification_type: NotificationTypeEnum,
			channel: NotificationChannelEnum,
			is_enabled: z.boolean().optional(),
			quiet_hours_start: z.string().optional(),
			quiet_hours_end: z.string().optional(),
		}),
	)
	.openapi('NotificationPreferenceUpdate');

// ---------------------------------------------------------------------------
// Unread count schema
// ---------------------------------------------------------------------------

export const UnreadCountDataSchema = z
	.object({
		unread_count: z.number().int(),
		has_unread: z.boolean(),
	})
	.openapi('UnreadCountData');

export const UnreadCountResponseSchema = ApiResponseSchema(UnreadCountDataSchema).openapi('UnreadCountResponse');
export type UnreadCountResponse = z.infer<typeof UnreadCountResponseSchema>;

// ---------------------------------------------------------------------------
// Notification device schema
// ---------------------------------------------------------------------------

export const NotificationDeviceSchema = z
	.object({
		id: z.uuid(),
		user_id: z.uuid(),
		platform: NotificationPlatformEnum,
		device_id: z.string(),
		device_name: z.string().nullable(),
		push_token: z.string().nullable(),
		one_signal_player_id: z.string().nullable(),
		device_info: z.record(z.string(), z.unknown()).nullable(),
		is_active: z.boolean(),
		last_used_at: z.iso.datetime().nullable(),
		created_at: z.iso.datetime(),
		updated_at: z.iso.datetime().nullable(),
	})
	.openapi('NotificationDevice');

export type NotificationDevice = z.infer<typeof NotificationDeviceSchema>;

export const NotificationDeviceRegisterSchema = z
	.object({
		platform: NotificationPlatformEnum.openapi({ example: 'ios' }),
		device_id: z.string().openapi({ example: 'device_token_abc123' }),
		device_name: z.string().optional().openapi({ example: 'iPhone 15 Pro' }),
		push_token: z.string().optional().openapi({ example: 'push_token_xyz789' }),
		one_signal_player_id: z.string().optional().openapi({ example: 'one_signal_id_123' }),
		device_info: z
			.record(z.string(), z.unknown())
			.optional()
			.openapi({
				example: {
					os: 'iOS 17.0',
					app_version: '1.0.0',
					model: 'iPhone 15 Pro',
				},
			}),
	})
	.openapi('NotificationDeviceRegister');

// ---------------------------------------------------------------------------
// Batch preview link schema
// ---------------------------------------------------------------------------

export const BatchPreviewLinkRequestSchema = z
	.object({
		file_ids: z
			.array(z.uuid())
			.max(100)
			.openapi({
				example: ['550e8400-e29b-41d4-a716-446655440000', '550e8400-e29b-41d4-a716-446655440001'],
			}),
	})
	.openapi('BatchPreviewLinkRequest');

export const BatchPreviewLinkResultSchema = z
	.array(
		z.object({
			file_id: z.uuid(),
			preview_url: z.string().nullable(),
			expires_in: z.number().nullable(),
			error: z.string().optional(),
		}),
	)
	.openapi('BatchPreviewLinkResult');

export const BatchPreviewLinkResponseSchema =
	ApiResponseSchema(BatchPreviewLinkResultSchema).openapi('BatchPreviewLinkResponse');
export type BatchPreviewLinkResponse = z.infer<typeof BatchPreviewLinkResponseSchema>;
