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

extendZodWithOpenApi(z);

// ---------------------------------------------------------------------------
// Shared
// ---------------------------------------------------------------------------

const REMINDER_TYPES = ['BEFORE_DUE', 'AFTER_DUE', 'ON_DUE_DATE'] as const;
const STATUSES = ['ACTIVE', 'INACTIVE'] as const;
const TARGET_TYPES = ['ALL', 'BUILDING', 'APARTMENT', 'ROOM', 'RESIDENT'] as const;
const CHANNELS = ['APP_PUSH', 'SMS', 'EMAIL', 'ZALO'] as const;

// ---------------------------------------------------------------------------
// Target entry schema (for request body)
// ---------------------------------------------------------------------------

export const PolicyTargetEntrySchema = z
	.object({
		targetType: z.enum(TARGET_TYPES),
		targetId: z.string().uuid().optional().nullable(),
	})
	.refine(
		(v) => v.targetType === 'ALL' || (v.targetId !== undefined && v.targetId !== null),
		{ message: 'targetId must not be empty when targetType is not "ALL"', path: ['targetId'] },
	)
	.openapi('PolicyTargetEntry');

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

export const DebtReminderPolicyCreateBodySchema = z
	.object({
		name: z.string().min(1).max(255),
		reminderType: z.enum(REMINDER_TYPES),
		daysOffset: z.number().int(),
		sendTime: z.string().regex(/^([0-1]\d|2[0-3]):([0-5]\d)$/, 'Invalid time format, expected HH:MM'),
		channels: z.array(z.enum(CHANNELS)).min(1),
		status: z.enum(STATUSES).default('ACTIVE'),
		targets: z.array(PolicyTargetEntrySchema).min(1),
	})
	.openapi('DebtReminderPolicyCreateBody');

export const DebtReminderPolicyUpdateBodySchema = z
	.object({
		name: z.string().min(1).max(255).optional(),
		reminderType: z.enum(REMINDER_TYPES).optional(),
		daysOffset: z.number().int().optional(),
		sendTime: z.string().regex(/^([0-1]\d|2[0-3]):([0-5]\d)$/, 'Invalid time format, expected HH:MM').optional(),
		channels: z.array(z.enum(CHANNELS)).min(1).optional(),
		status: z.enum(STATUSES).optional(),
		targets: z.array(PolicyTargetEntrySchema).min(1).optional(),
	})
	.openapi('DebtReminderPolicyUpdateBody');

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

export const PolicyTargetSchema = z.object({
	id: z.string().uuid(),
	policy_id: z.string().uuid(),
	target_type: z.string(),
	target_id: z.string().uuid().nullable(),
	target_details: z
		.object({
			name: z.string().optional(),
			code: z.string().optional(),
			floor: z.number().optional(),
			full_name: z.string().optional(),
			phone: z.string().optional(),
			email: z.string().optional(),
			id_card: z.string().optional(),
		})
		.nullable()
		.optional(),
	created_by: z.string().uuid().nullable(),
	updated_by: z.string().uuid().nullable(),
	created_at: z.string().datetime(),
	updated_at: z.string().datetime(),
}).openapi('PolicyTarget');

export const DebtReminderPolicyListItemSchema = z.object({
	id: z.string().uuid(),
	name: z.string(),
	reminder_type: z.string(),
	days_offset: z.number(),
	send_time: z.string(),
	channels: z.any(),
	status: z.string(),
	created_by: z.string().uuid().nullable(),
	updated_by: z.string().uuid().nullable(),
	created_at: z.string().datetime(),
	updated_at: z.string().datetime(),
}).openapi('DebtReminderPolicyListItem');

export const DebtReminderPolicyDetailSchema = z.object({
	id: z.string().uuid(),
	name: z.string(),
	reminder_type: z.string(),
	days_offset: z.number(),
	send_time: z.string(),
	channels: z.any(),
	status: z.string(),
	targets: z.array(PolicyTargetSchema),
	created_by: z.string().uuid().nullable(),
	updated_by: z.string().uuid().nullable(),
	created_at: z.string().datetime(),
	updated_at: z.string().datetime(),
}).openapi('DebtReminderPolicyDetail');

export const DebtReminderPolicyListDataSchema = z.object({
	count: z.number(),
	rows: z.array(DebtReminderPolicyListItemSchema),
	page: z.number(),
	pageSize: z.number(),
}).openapi('DebtReminderPolicyListData');

export const DebtReminderPolicyResponseSchema = ApiResponseSchema(DebtReminderPolicyDetailSchema).openapi('DebtReminderPolicyResponse');
export const DebtReminderPolicyListResponseSchema = ApiResponseSchema(DebtReminderPolicyListDataSchema).openapi('DebtReminderPolicyListResponse');
