import type { FastifyInstance, FastifyPluginAsync } from 'fastify';

interface RegisterBody {
  email: string;
  password: string;
  name: string;
}

interface LoginBody {
  email: string;
  password: string;
}

interface GoogleAuthBody {
  token: string;
}

interface GoogleUserInfo {
  email: string;
  name: string;
  sub: string;
}

const authRoutes: FastifyPluginAsync = async (fastify: FastifyInstance) => {
  // --- Inscription ---
  fastify.post<{ Body: RegisterBody }>(
    '/register',
    {
      schema: {
        body: {
          type: 'object',
          required: ['email', 'password', 'name'],
          properties: {
            email: { type: 'string', format: 'email' },
            password: { type: 'string', minLength: 6 },
            name: { type: 'string' },
          },
        },
      },
    },
    async (request, reply) => {
      const { email, password, name } = request.body;

      try {
        const existingUser = await fastify.prisma.user.findUnique({ where: { email } });
        if (existingUser) {
          return reply.code(400).send({ error: 'Cet email est déjà utilisé' });
        }

        // Créer un client Stripe (le plugin peut être désactivé)
        let stripeId = '';
        if (fastify.createCustomer) {
          const customer = await fastify.createCustomer(email, name);
          stripeId = customer.id;
        }

        const hashedPassword = await fastify.hashPassword(password);

        const user = await fastify.prisma.user.create({
          data: {
            email,
            password: hashedPassword,
            name,
            stripeId,
          },
        });

        const token = fastify.jwt.sign({ id: user.id }, { expiresIn: '7d' });

        return {
          user: {
            id: user.id,
            email: user.email,
            name: user.name,
            subscription: user.subscription,
          },
          token,
        };
      } catch (error) {
        fastify.log.error(error);
        return reply.code(500).send({ error: "Erreur lors de l'inscription" });
      }
    }
  );

  // --- Connexion ---
  fastify.post<{ Body: LoginBody }>(
    '/login',
    {
      schema: {
        body: {
          type: 'object',
          required: ['email', 'password'],
          properties: {
            email: { type: 'string', format: 'email' },
            password: { type: 'string' },
          },
        },
      },
    },
    async (request, reply) => {
      const { email, password } = request.body;

      try {
        const user = await fastify.prisma.user.findUnique({ where: { email } });

        if (!user || !user.password) {
          return reply.code(401).send({ error: 'Email ou mot de passe incorrect' });
        }

        const passwordMatch = await fastify.comparePassword(password, user.password);
        if (!passwordMatch) {
          return reply.code(401).send({ error: 'Email ou mot de passe incorrect' });
        }

        const token = fastify.jwt.sign({ id: user.id }, { expiresIn: '7d' });

        return {
          user: {
            id: user.id,
            email: user.email,
            name: user.name,
            subscription: user.subscription,
          },
          token,
        };
      } catch (error) {
        fastify.log.error(error);
        return reply.code(500).send({ error: 'Erreur lors de la connexion' });
      }
    }
  );

  // --- Google OAuth ---
  fastify.post<{ Body: GoogleAuthBody }>(
    '/google-auth',
    {
      schema: {
        body: {
          type: 'object',
          required: ['token'],
          properties: {
            token: { type: 'string' },
          },
        },
      },
    },
    async (request, reply) => {
      const { token } = request.body;

      try {
        const response = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', {
          headers: { Authorization: `Bearer ${token}` },
        });

        if (!response.ok) {
          throw new Error('Impossible de récupérer les informations utilisateur');
        }

        const userData = (await response.json()) as GoogleUserInfo;
        const { email, name, sub: googleId } = userData;

        let user = await fastify.prisma.user.findUnique({ where: { email } });

        if (!user) {
          let stripeId = '';
          if (fastify.createCustomer) {
            const customer = await fastify.createCustomer(email, name);
            stripeId = customer.id;
          }

          user = await fastify.prisma.user.create({
            data: { email, name, googleId, stripeId },
          });
        } else if (!user.googleId) {
          user = await fastify.prisma.user.update({
            where: { id: user.id },
            data: { googleId },
          });
        }

        const jwtToken = fastify.jwt.sign({ id: user.id }, { expiresIn: '7d' });

        return {
          user: {
            id: user.id,
            email: user.email,
            name: user.name,
            subscription: user.subscription,
          },
          token: jwtToken,
        };
      } catch (error) {
        fastify.log.error(error);
        return reply.code(500).send({ error: "Erreur lors de l'authentification Google" });
      }
    }
  );
};

export default authRoutes;
