import { Application } from 'express';
import { Resource } from 'express-automatic-routes';
import { ResidentProvider } from '#providers/ResidentProvider';
import { ResidentDocumentProvider } from '#providers/ResidentDocumentProvider';
import { Req, Res } from '#interfaces/IApi';
import verify, { attachPermissions, requireAdmin } from '#middlewares/auth';
import { validateId } from '#middlewares/validators';
import { validateZod } from '#middlewares/validators';
import { z } from 'zod';
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
import { Errors } from '#interfaces/error';
import { sendSuccess } from '#utils/responseUtils';

extendZodWithOpenApi(z);

const DocumentTypeEnum = z.enum([
	'id_card',
	'cccd_front',
	'cccd_back',
	'portrait',
	'passport',
	'household_registration',
	'temporary_residence',
	'contract',
	'other',
]);

const ResidentDocumentCreateBodySchema = z
	.object({
		file_id: z.uuid().describe('ID of the uploaded file from /api/v1/files'),
		document_type: DocumentTypeEnum.openapi({ example: 'portrait' }),
		document_name: z.string().max(255).optional().openapi({ example: 'ảnh chân dung' }),
		description: z.string().optional().openapi({ example: 'string' }),
		is_primary: z.boolean().optional().default(false).openapi({ example: false }),
	})
	.openapi('ResidentDocumentCreateBody');

// Main schema: array of documents
export const ResidentDocumentBatchCreateBodySchema = z
	.array(ResidentDocumentCreateBodySchema)
	.min(1, 'At least one document is required')
	.openapi('ResidentDocumentBatchCreateBody');

export default (_express: Application) => {
	const residentProvider = new ResidentProvider();
	const documentProvider = ResidentDocumentProvider.getInstance();

	return <Resource>{
		get: {
			middleware: [verify, validateId],
			handler: async (req: Req, res: Res) => {
				try {
					// Check if resident exists
					const resident = await residentProvider.getById({ id: req.params.id! });
					if (!resident) throw Errors.notFound('Resident');

					const isAdmin = req.user?.roles?.some((r) => ['admin', 'system_admin'].includes(r));
					if (!isAdmin && req.user?.id !== resident.user_id) {
						throw Errors.forbidden();
					}

					const data = await documentProvider.getAll({
						where: { resident_id: req.params.id! } as any,
					});
					return sendSuccess(res, data);
				} catch (error) {
					return res.error(error);
				}
			},
		},
		post: {
			middleware: [verify, attachPermissions, validateId, validateZod(ResidentDocumentBatchCreateBodySchema)],
			handler: async (req: Req, res: Res) => {
				try {
					// Check if resident exists
					const resident = await residentProvider.getById({ id: req.params.id! });
					if (!resident) throw Errors.notFound('Resident');

					// req.body is already validated by validateZod middleware
					const validated = req.body as z.infer<typeof ResidentDocumentBatchCreateBodySchema>;

					// Create all documents
					const createdDocuments = await Promise.all(
						validated.map((doc) =>
							documentProvider.create({
								file_id: doc.file_id,
								document_type: doc.document_type,
								document_name: doc.document_name || null,
								description: doc.description || null,
								is_primary: doc.is_primary ?? false,
								resident_id: req.params.id!,
								created_by: req.user?.id || null,
								status : req.user?.permissions?.includes('document:create') ? 'approved' : 'pending',
							} as any),
						),
					);

					return sendSuccess(res, createdDocuments);
				} catch (error) {
					return res.error(error);
				}
			},
		},
	};
};
