import passport from 'passport';
import { Strategy as LocalStrategy } from 'passport-local';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
import bcrypt from 'bcryptjs';
import { db } from '../db/index.js';
import { users } from '../db/schema.js';
import { eq } from 'drizzle-orm';

passport.serializeUser((user, done) => done(null, user.id));

passport.deserializeUser(async (id, done) => {
  try {
    const rows = await db.select().from(users).where(eq(users.id, id)).limit(1);
    if (rows.length === 0) return done(null, false);
    const u = rows[0];
    delete u.passwordHash;
    done(null, u);
  } catch (err) {
    done(err);
  }
});

passport.use(
  new LocalStrategy(
    { usernameField: 'email', passwordField: 'password' },
    async (email, password, done) => {
      try {
        const rows = await db
          .select()
          .from(users)
          .where(eq(users.email, email.toLowerCase().trim()))
          .limit(1);

        if (rows.length === 0) return done(null, false, { message: 'Email atau password salah.' });
        const u = rows[0];
        if (!u.passwordHash) return done(null, false, { message: 'Akun ini hanya bisa login via Google.' });

        const ok = await bcrypt.compare(password, u.passwordHash);
        if (!ok) return done(null, false, { message: 'Email atau password salah.' });
        return done(null, u);
      } catch (err) {
        return done(err);
      }
    },
  ),
);

if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET) {
  passport.use(
    new GoogleStrategy(
      {
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: process.env.GOOGLE_CALLBACK_URL || '/auth/google/callback',
      },
      async (accessToken, refreshToken, profile, done) => {
        try {
          const email = profile.emails?.[0]?.value?.toLowerCase();
          if (!email) return done(null, false, { message: 'Email Google tidak tersedia.' });

          // Cari user existing by google_id atau email
          let rows = await db.select().from(users).where(eq(users.googleId, profile.id)).limit(1);
          if (rows.length === 0) {
            rows = await db.select().from(users).where(eq(users.email, email)).limit(1);
            if (rows.length > 0) {
              await db.update(users).set({ googleId: profile.id }).where(eq(users.id, rows[0].id));
            }
          }
          if (rows.length === 0) {
            return done(null, false, { message: 'Akun Google belum terdaftar. Hubungi admin.' });
          }
          return done(null, rows[0]);
        } catch (err) {
          return done(err);
        }
      },
    ),
  );
}

export default passport;
