const passport = require('passport');
const { Strategy: GoogleStrategy } = require('passport-google-oauth20');
const jwt = require('jsonwebtoken');
const db = require('../db');

function deriveBase(email) {
  const local = email.split('@')[0];
  const sanitized = local
    .replace(/\./g, '_')
    .replace(/[^a-zA-Z0-9_]/g, '')
    .slice(0, 15)
    .toLowerCase();
  return sanitized || 'user';
}

async function generateUniqueUsername(email) {
  const base = deriveBase(email);
  const taken = await db.user.findFirst({ where: { username: base } });
  if (!taken) return base;
  let attempts = 0;
  while (attempts < 20) {
    const suffix = String(Math.floor(1000 + Math.random() * 9000));
    const username = `${base}_${suffix}`;
    const collision = await db.user.findFirst({ where: { username } });
    if (!collision) return username;
    attempts++;
  }
  return `${base}_${Date.now()}`;
}

passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: process.env.GOOGLE_CALLBACK_URL,
    },
    async (_accessToken, _refreshToken, profile, done) => {
      try {
        const email = profile.emails?.[0]?.value ?? '';
        let user = await db.user.findUnique({ where: { googleId: profile.id } });

        if (!user) {
          const username = await generateUniqueUsername(email);
          user = await db.user.create({
            data: {
              googleId: profile.id,
              email,
              displayName: profile.displayName,
              avatarUrl: profile.photos?.[0]?.value ?? null,
              username,
            },
          });
        } else {
          user = await db.user.update({
            where: { googleId: profile.id },
            data: {
              email,
              displayName: profile.displayName,
              avatarUrl: profile.photos?.[0]?.value ?? null,
            },
          });
          if (!user.username) {
            const username = await generateUniqueUsername(user.email ?? '');
            user = await db.user.update({ where: { id: user.id }, data: { username } });
          }
        }

        const token = jwt.sign(
          {
            userId: user.id,
            email: user.email,
            name: user.displayName,
            picture: user.avatarUrl,
          },
          process.env.JWT_SECRET,
          { algorithm: 'HS256', expiresIn: '7d' }
        );

        done(null, { token });
      } catch (err) {
        done(err);
      }
    }
  )
);

module.exports = passport;
