import { z } from 'zod';
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
import { ApiResponseSchema, uuidSchema } from '../shared';

extendZodWithOpenApi(z);

// ============================================================================
// Contract Type (Reference to contract_types table)
// ============================================================================

export const ContractTypeSchema = z
	.object({
		id: uuidSchema.openapi({ description: 'Contract Type ID' }),
		code: z.string().openapi({ description: 'Contract type code (residential_lease, room_rental, service_agreement, other)' }),
		name_vi: z.string().openapi({ description: 'Contract type name in Vietnamese' }),
		name_en: z.string().nullable().openapi({ description: 'Contract type name in English' }),
		description: z.string().nullable().openapi({ description: 'Description' }),
		created_at: z.string().datetime().openapi({ description: 'Created at' }),
		updated_at: z.string().datetime().openapi({ description: 'Updated at' }),
	})
	.openapi('ContractType');

// ============================================================================
// Contract Response Schema
// ============================================================================

export const ContractSchema = z
	.object({
		id: uuidSchema.openapi({ description: 'Contract ID' }),
		resident_id: uuidSchema.openapi({ description: 'Resident ID (Cư dân)' }),
		contract_number: z
			.string()
			.min(1)
			.max(100)
			.openapi({ description: 'Contract number (Mã HĐ)' }),
		contract_name: z
			.string()
			.max(255)
			.nullable()
			.openapi({ description: 'Contract name (Tên HĐ)' }),
		contract_type_id: uuidSchema.openapi({ description: 'Contract Type ID (Reference to contract_types table)' }),
		description: z
			.string()
			.nullable()
			.openapi({ description: 'Description (Mô tả)' }),
		rent_amount: z
			.number()
			.positive()
			.nullable()
			.openapi({ description: 'Rent amount (Giá thuê)' }),
		deposit_amount: z
			.number()
			.positive()
			.nullable()
			.openapi({ description: 'Deposit amount (Tiền coc)' }),
		payment_day: z
			.number()
			.int()
			.min(1)
			.max(31)
			.nullable()
			.openapi({ description: 'Payment day of month (Chu kỳ TT: 1-31)' }),
		signed_date: z
			.string()
			.date()
			.nullable()
			.openapi({ description: 'Signed date (Ngày ký)' }),
		expiry_date: z
			.string()
			.date()
			.nullable()
			.openapi({ description: 'Expiry date (Ngày hết hạn)' }),
		created_by: uuidSchema
			.nullable()
			.openapi({ description: 'Created by (Tạo bởi)' }),
		updated_by: uuidSchema
			.nullable()
			.openapi({ description: 'Updated by (Cập nhật bởi)' }),
		created_at: z
			.string()
			.datetime()
			.openapi({ description: 'Created at' }),
		updated_at: z
			.string()
			.datetime()
			.openapi({ description: 'Updated at' }),
		deleted_at: z
			.string()
			.datetime()
			.nullable()
			.openapi({ description: 'Deleted at (soft delete)' }),
	})
	.openapi('Contract');

// ============================================================================
// Request Schemas
// ============================================================================

export const ContractCreateBodySchema = z
	.object({
		resident_id: uuidSchema.openapi({ description: 'Resident ID' }),
		contract_number: z
			.string()
			.min(1, 'Contract number required')
			.max(100, 'Contract number must be max 100 characters')
			.openapi({ description: 'Contract number (Mã HĐ)' }),
		contract_name: z
			.string()
			.max(255, 'Contract name must be max 255 characters')
			.optional()
			.openapi({ description: 'Contract name (Tên HĐ)' }),
		contract_type_id: uuidSchema.openapi({ description: 'Contract Type ID (Loại HĐ)' }),
		description: z
			.string()
			.optional()
			.openapi({ description: 'Description (Mô tả)' }),
		rent_amount: z
			.number()
			.positive('Rent amount must be positive')
			.optional()
			.openapi({ description: 'Rent amount (Giá thuê)' }),
		deposit_amount: z
			.number()
			.positive('Deposit amount must be positive')
			.optional()
			.openapi({ description: 'Deposit amount (Tiền coc)' }),
		payment_day: z
			.number()
			.int()
			.min(1, 'Payment day must be 1-31')
			.max(31, 'Payment day must be 1-31')
			.optional()
			.openapi({ description: 'Payment day (Chu kỳ TT: 1-31)' }),
		signed_date: z
			.string()
			.date('Invalid date format')
			.optional()
			.openapi({ description: 'Signed date (Ngày ký)' }),
		expiry_date: z
			.string()
			.date('Invalid date format')
			.optional()
			.openapi({ description: 'Expiry date (Ngày hết hạn)' }),
	})
	.openapi('ContractCreateBody');

export const ContractUpdateBodySchema = z
	.object({
		contract_number: z
			.string()
			.min(1)
			.max(100)
			.optional()
			.openapi({ description: 'Contract number' }),
		contract_name: z
			.string()
			.max(255)
			.optional()
			.openapi({ description: 'Contract name' }),
		contract_type_id: uuidSchema.optional().openapi({ description: 'Contract Type ID' }),
		description: z
			.string()
			.optional()
			.openapi({ description: 'Description' }),
		rent_amount: z
			.number()
			.positive()
			.optional()
			.openapi({ description: 'Rent amount' }),
		deposit_amount: z
			.number()
			.positive()
			.optional()
			.openapi({ description: 'Deposit amount' }),
		payment_day: z
			.number()
			.int()
			.min(1)
			.max(31)
			.optional()
			.openapi({ description: 'Payment day' }),
		signed_date: z
			.string()
			.date()
			.optional()
			.openapi({ description: 'Signed date' }),
		expiry_date: z
			.string()
			.date()
			.optional()
			.openapi({ description: 'Expiry date' }),
	})
	.openapi('ContractUpdateBody');

export const ContractVerifyBodySchema = z
	.object({
		verified_by: uuidSchema.openapi({ description: 'User ID verifying' }),
	})
	.openapi('ContractVerifyBody');

// ============================================================================
// Response Schemas
// ============================================================================

export const ContractResponseSchema = ApiResponseSchema(ContractSchema).openapi('ContractResponse');

export const ContractListResponseSchema = ApiResponseSchema(
	z.object({
		items: z.array(ContractSchema),
		total: z.number(),
		page: z.number(),
		limit: z.number(),
	}),
).openapi('ContractListResponse');

export type ContractType = z.infer<typeof ContractTypeSchema>;
export type Contract = z.infer<typeof ContractSchema>;
export type ContractCreateBody = z.infer<typeof ContractCreateBodySchema>;
export type ContractUpdateBody = z.infer<typeof ContractUpdateBodySchema>;
export type ContractVerifyBody = z.infer<typeof ContractVerifyBodySchema>;
