import { z } from 'zod';
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
import { ApiResponseSchema, QueryParamsSchema } from '#contracts/shared';

extendZodWithOpenApi(z);

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

const AuditSeverityEnum = z.enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']);
const InvestigationStatusEnum = z.enum(['PENDING', 'INVESTIGATING', 'RESOLVED', 'IGNORED']);

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

export const AuditLogQuerySchema = QueryParamsSchema.openapi('AuditLogQuery');

export const EntityChangeHistoryQuerySchema = QueryParamsSchema.extend({
	entity_type: z.string().openapi({ example: 'Resident', description: 'Type of entity (e.g., Resident, Contract)' }),
	entity_id: z
		.string()
		.uuid()
		.openapi({ example: '123e4567-e89b-12d3-a456-426614174000', description: 'ID of the entity' }),
}).openapi('EntityChangeHistoryQuery');

export const AuditExportQuerySchema = QueryParamsSchema.extend({
	maxRecords: z.coerce
		.number()
		.int()
		.min(1)
		.max(10000)
		.optional()
		.openapi({ example: 10000, description: 'Maximum number of records to export (max 10000)' }),
}).openapi('AuditExportQuery');

export const DeadLetterQuerySchema = QueryParamsSchema.openapi('DeadLetterQuery');

// ---------------------------------------------------------------------------
// Response schemas
// ---------------------------------------------------------------------------

export const AuditLogItemSchema = z
	.object({
		id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174000' }),
		outbox_event_id: z.uuid().nullable().openapi({ example: '123e4567-e89b-12d3-a456-426614174001' }),
		request_id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174002' }),
		trace_id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174003' }),
		session_id: z.uuid().nullable().openapi({ example: '123e4567-e89b-12d3-a456-426614174004' }),
		tenant_id: z.uuid().nullable().openapi({ example: '123e4567-e89b-12d3-a456-426614174005' }),
		actor_id: z.uuid().nullable().openapi({ example: '123e4567-e89b-12d3-a456-426614174006' }),
		actor_name: z.string().nullable().openapi({ example: 'Nguyễn Văn A' }),
		actor_email: z.string().nullable().openapi({ example: 'nguyenvana@example.com' }),
		actor_role: z.string().nullable().openapi({ example: 'ADMIN' }),
		action: z.string().openapi({ example: 'CREATE_RESIDENT' }),
		module: z.string().openapi({ example: 'CRM' }),
		entity_id: z.uuid().nullable().openapi({ example: '123e4567-e89b-12d3-a456-426614174007' }),
		entity_type: z.string().nullable().openapi({ example: 'Resident' }),
		batch_id: z.uuid().nullable().openapi({ example: '123e4567-e89b-12d3-a456-426614174008' }),
		description: z.string().nullable().openapi({ example: 'Created new resident' }),
		severity: AuditSeverityEnum.openapi({ example: 'MEDIUM' }),
		ip_address: z.string().nullable().openapi({ example: '192.168.1.1' }),
		user_agent: z.string().nullable().openapi({ example: 'Mozilla/5.0' }),
		payload: z.record(z.string(), z.unknown()).nullable(),
		payload_size: z.number().int().nullable().openapi({ example: 1024 }),
		success: z.boolean().nullable().openapi({ example: true }),
		failure_reason: z.string().nullable().openapi({ example: null }),
		event_version: z.number().int().openapi({ example: 1 }),
		created_at: z.iso.datetime().openapi({ example: '2024-01-15T08:30:00Z' }),
	})
	.openapi('AuditLogItem');

export const AuditLogListDataSchema = z
	.object({
		count: z.number().int().openapi({ example: 100 }),
		rows: z.array(AuditLogItemSchema),
		page: z.number().int().openapi({ example: 1 }),
		pageSize: z.number().int().openapi({ example: 50 }),
	})
	.openapi('AuditLogListData');

export const AuditLogListResponseSchema = ApiResponseSchema(AuditLogListDataSchema).openapi('AuditLogListResponse');

export const AuditLogByIdDataSchema = z
	.object({
		count: z.number().int().openapi({ example: 10 }),
		rows: z.array(AuditLogItemSchema),
	})
	.openapi('AuditLogByIdData');

export const AuditLogByIdResponseSchema = ApiResponseSchema(AuditLogByIdDataSchema).openapi('AuditLogByIdResponse');

export const DeadLetterItemSchema = z
	.object({
		id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174010' }),
		original_event_id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174011' }),
		event_type: z.string().openapi({ example: 'SYSTEM_AUDIT' }),
		original_payload: z.record(z.string(), z.unknown()).openapi({ example: { action: 'CREATE_RESIDENT' } }),
		error_message: z.string().openapi({ example: 'Database connection failed' }),
		error_stack: z.string().nullable().openapi({ example: null }),
		failed_at: z.iso.datetime().openapi({ example: '2024-01-15T08:30:00Z' }),
		replayed: z.boolean().openapi({ example: false }),
		replayed_at: z.iso.datetime().nullable().openapi({ example: null }),
		replay_count: z.number().int().openapi({ example: 0 }),
		investigation_status: InvestigationStatusEnum.openapi({ example: 'PENDING' }),
		resolution_notes: z.string().nullable().openapi({ example: null }),
		created_at: z.iso.datetime().openapi({ example: '2024-01-15T08:30:00Z' }),
	})
	.openapi('DeadLetterItem');

export const DeadLetterListDataSchema = z
	.object({
		count: z.number().int().openapi({ example: 10 }),
		rows: z.array(DeadLetterItemSchema),
		page: z.number().int().openapi({ example: 1 }),
		pageSize: z.number().int().openapi({ example: 50 }),
	})
	.openapi('DeadLetterListData');

export const DeadLetterListResponseSchema =
	ApiResponseSchema(DeadLetterListDataSchema).openapi('DeadLetterListResponse');

export const DeadLetterReplayResponseSchema = ApiResponseSchema(
	z.object({
		message: z.string().openapi({ example: 'Event replayed successfully' }),
		new_outbox_event_id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174020' }),
	}),
).openapi('DeadLetterReplayResponse');

export const EntityChangeItemSchema = z
	.object({
		id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174000' }),
		entity_type: z.string().openapi({ example: 'Resident' }),
		entity_id: z.uuid().openapi({ example: '123e4567-e89b-12d3-a456-426614174000' }),
		change_type: z.string().openapi({ example: 'UPDATE' }),
		actor_id: z.uuid().nullable().openapi({ example: '123e4567-e89b-12d3-a456-426614174001' }),
		actor_name: z.string().nullable().openapi({ example: 'Admin' }),
		actor_email: z.string().nullable().openapi({ example: 'admin@example.com' }),
		before: z.record(z.string(), z.unknown()).nullable().openapi({ example: null }),
		after: z
			.record(z.string(), z.unknown())
			.nullable()
			.openapi({ example: { phone: '0912345678' } }),
		changed_fields: z.array(z.string()).openapi({ example: ['phone'] }),
		reason: z.string().nullable().openapi({ example: 'Cập nhật SĐT' }),
		created_at: z.iso.datetime().openapi({ example: '2024-03-10T14:30:00Z' }),
	})
	.openapi('EntityChangeItem');

export const EntityChangeHistoryDataSchema = z
	.object({
		count: z.number().int().openapi({ example: 10 }),
		rows: z.array(EntityChangeItemSchema),
	})
	.openapi('EntityChangeHistoryData');

export const EntityChangeHistoryResponseSchema =
	ApiResponseSchema(EntityChangeHistoryDataSchema).openapi('EntityChangeHistoryResponse');

export const AuditExportResponseSchema = ApiResponseSchema(
	z.object({
		message: z.string().openapi({ example: 'CSV file generated successfully' }),
		record_count: z.number().int().openapi({ example: 100 }),
	}),
).openapi('AuditExportResponse');
