import { Application } from 'express';
import { Resource } from 'express-automatic-routes';
import { ResidentDocumentProvider } from '#providers/ResidentDocumentProvider';
import { Req, Res } from '#interfaces/IApi';
import verify, { requireAdmin } from '#middlewares/auth';
import { validateParamsZod, validateZod } from '#middlewares/validators';
import { z } from 'zod';
import { Errors } from '#interfaces/error';
import { sendSuccess } from '#utils/responseUtils';

const ResidentDocumentUpdateSchema = z.object({
  file_id: z.string().uuid().optional(),
  document_type: z
    .enum([
      'id_card',
      'cccd_front',
      'cccd_back',
      'portrait',
      'passport',
      'household_registration',
      'temporary_residence',
      'contract',
      'other',
    ])
    .optional(),
  document_name: z.string().max(255).nullable().optional(),
  description: z.string().nullable().optional(),
  is_primary: z.boolean().optional(),
  issued_date: z.string().optional(),
  expiry_date: z.string().optional(),
  status: z.enum(['pending', 'approved', 'rejected']).optional(),
});

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

  return <Resource>{
    put: {
      middleware: [verify, requireAdmin, validateParamsZod(z.object({ document_id: z.string().uuid() })), validateZod(ResidentDocumentUpdateSchema)],
      handler: async (req: Req, res: Res) => {
        try {
          const documentId = req.params.document_id!;

          const document = await documentProvider.getById({ id: documentId });
          if (!document) throw Errors.notFound('ResidentDocument');

          const updates = req.body as z.infer<typeof ResidentDocumentUpdateSchema>;

          const updateBody: any = {
            ...('file_id' in updates ? { file_id: updates.file_id } : {}),
            ...('document_type' in updates ? { document_type: updates.document_type } : {}),
            ...('document_name' in updates ? { document_name: updates.document_name } : {}),
            ...('description' in updates ? { description: updates.description } : {}),
            ...('is_primary' in updates ? { is_primary: updates.is_primary } : {}),
            ...('issued_date' in updates ? { issued_date: updates.issued_date } : {}),
            ...('expiry_date' in updates ? { expiry_date: updates.expiry_date } : {}),
            ...('status' in updates ? { status: updates.status } : {}),
            updated_at: new Date(),
            updated_by: req.user?.id || null,
          };

          if ('status' in updates) {
            if (updates.status === 'approved') {
              updateBody.verified_at = new Date();
              updateBody.verified_by = req.user?.id || null;
            } else {
              updateBody.verified_at = null;
              updateBody.verified_by = null;
            }
          }

          const updated = await documentProvider.put(documentId, updateBody as any);

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