import { FastifyInstance } from "fastify";
import { ZodTypeProvider } from "fastify-type-provider-zod";
import { z } from "zod";
import { prisma } from "../../lib/prisma";
import { auth } from "../../middlewares/auth";
import { BadRequest } from "../_errors/bad-request";
import { UnauthorizedError } from "../_errors/unauthorized-error";
import { cpfSchema } from "../../utils/validate-cpf";

export async function createUser(app: FastifyInstance) {
  // Registrar o middleware de autenticação
  app.register(auth);

  app
    .withTypeProvider<ZodTypeProvider>()
    .post('/users', {
      schema: {
        summary: 'Create a user',
        tags: ['users'],
        security: [{ bearerAuth: [] }],  // Adiciona a configuração de segurança
        body: z.object({
          name: z.string().min(4),
          email: z.string().email(),
          phone: z.string().min(9),
          cpf: z.string().min(11),
          zip: z.string().min(8),
          address: z.string().min(4),
          number: z.string().nullable(),
          complement: z.string().nullable(),
          district: z.string().nullable(),
          city: z.string().min(2),
          state: z.string().min(2),
          details: z.string().nullable(),
          role: z.enum(["manager", "customer"]),
        }),
        response: {
          201: z.object({
            userId: z.string().cuid(),
          }),
          400: z.object({
            error: z.string(),
          }),
          401: z.object({
            error: z.string(),
          }),
          500: z.object({
            error: z.string(),
          }),
        },
      },
    }, async (request, reply) => {
      try {
        console.log("Handler start");

        // Obter o ID do usuário atual
        const userId = await request.getCurrentUserId();
        console.log("User ID:", userId);

        // Verifica se o usuário é Admin (manager)
        const userVerify = await prisma.user.findUnique({
          where: {
            id: userId
          }
        });
        console.log("User Verify:", userVerify);

        if (!userVerify) {
          throw new UnauthorizedError('User not found.');
        }

        if (userVerify.role !== 'manager') {
          throw new UnauthorizedError('You do not have permission to access this route');
        }

        const {
          name,
          email,
          phone,
          cpf,
          zip,
          address,
          number,
          complement,
          district,
          city,
          state,
          details,
          role
        } = request.body;

        // Verificar se o email já existe
        const existingEmail = await prisma.user.findFirst({
          where: {
            email: email,
          },
        });
        console.log("Existing Email:", existingEmail);

        if (existingEmail !== null) {
          throw new BadRequest('Another user with the same email already exists.');
        }

        const cpfValidation = cpfSchema.safeParse(cpf);
        console.log("CPF Validation:", cpfValidation);

        if (!cpfValidation.success) {
          throw new BadRequest('CPF invalid.');
        }

        const cpfNumbersOnly = cpf.replace(/\D/g, '');

        // Verificar se o CPF já existe
        const existingCpf = await prisma.user.findFirst({
          where: {
            cpf: cpfNumbersOnly,
          },
        });
        console.log("Existing CPF:", existingCpf);

        if (existingCpf !== null) {
          throw new BadRequest('Another user with the same CPF already exists.');
        }

        // Criar o novo usuário
        const user = await prisma.user.create({
          data: {
            name,
            email,
            phone: phone.replace(/\D/g, ''),
            cpf: cpfNumbersOnly,
            zip: zip.replace(/\D/g, ''),
            address,
            number,
            complement,
            district,
            city,
            state,
            details,
            role
          },
        });
        console.log("User Created:", user);

        return reply.status(201).send({ userId: user.id });
      } catch (error) {
        console.error("Error creating user:", error);
        
        let message = 'An unexpected error occurred';
        if (error instanceof UnauthorizedError || error instanceof BadRequest) {
          message = error.message;
        } else if (error instanceof Error) {
          message = error.message;
        }
        
        return reply.status(error instanceof UnauthorizedError ? 401 : error instanceof BadRequest ? 400 : 500).send({ error: message });
      }
    });
}
