// filepath: c:\Users\amaizy\Desktop\cvgen\controllers\linkedin.js

const axios = require("axios");
const querystring = require("querystring");
const { chromium } = require("playwright");

const clientId = "780w7gsy8eysmj";
const clientSecret = "WPL_AP1.w6OTTkAndAdT3PYF.UZEcwQ==";
const redirectUri = "http://localhost:4200/api/auth/linkedin/callback";
const scope = "openid profile email";

const email = "amaury@maizy.net";
const password = "2Qh*fJrp+l7M6g>8P~}/S$Bc2Yvf&-vd";

let accessToken = "";

const authenticateUser = (req, res) => {
  const authUrl = `https://www.linkedin.com/oauth/v2/authorization?${querystring.stringify(
    {
      response_type: "code",
      client_id: clientId,
      redirect_uri: redirectUri,
      scope: scope,
    }
  )}`;
  res.redirect(authUrl);
};

const handleCallback = async (req, res) => {
  const { code } = req.query;

  try {
    const tokenResponse = await axios.post(
      "https://www.linkedin.com/oauth/v2/accessToken",
      querystring.stringify({
        grant_type: "authorization_code",
        code: code,
        redirect_uri: redirectUri,
        client_id: clientId,
        client_secret: clientSecret,
      })
    );

    const accessToken = tokenResponse.data.access_token;

    // Stocke dans la session
    req.session.user = {
      accessToken,
    };

    // Redirige vers /profile après authentification
    res.redirect("/profile");
  } catch (error) {
    console.error(
      "LinkedIn token error:",
      error.response ? error.response.data : error.message
    );
    res.status(500).send("Error retrieving access token.");
  }
};

const getUserProfile = async (req, res) => {
  try {
    const token = req.session?.user?.accessToken;
    if (!token) {
      return res.status(401).json({ error: "Aucun accessToken en session." });
    }

    const { data } = await axios.get("https://api.linkedin.com/v2/userinfo", {
      headers: {
        Authorization: `Bearer ${token}`,
        Accept: "application/json",
      },
    });

    // Enregistre les infos utiles en session
    req.session.user.nom = data.given_name + " " + data.family_name;
    req.session.user.img = data.picture;
    req.session.user.email = data.email;

    // Redirige vers /me après authentification
    res.redirect("/me");
  } catch (error) {
    console.error(
      "LinkedIn OIDC error:",
      error.response?.data || error.message
    );
    return res
      .status(500)
      .json({ error: "Erreur lors de la récupération du profil." });
  }
};

const scrapeLinkedInProfile = async (profileUrl) => {
  console.log("Scraping LinkedIn profile:", profileUrl);

  const browser = await chromium.launch({
    headless: true,
    args: ["--no-sandbox", "--disable-setuid-sandbox"],
  });

  const page = await browser.newPage();

  try {
    // === 1. Login ===
    await page.goto("https://www.linkedin.com/login", {
      waitUntil: "domcontentloaded",
      timeout: 60000,
    });
    console.log("Login page loaded");
    await page.screenshot({
      path: "public/error/step1_login.png",
      fullPage: true,
    });

    await page.fill("#username", email, { delay: 50 });
    await page.fill("#password", password, { delay: 50 });

    await Promise.all([
      page.click('[type="submit"]'),
      page.waitForNavigation({ waitUntil: "domcontentloaded", timeout: 60000 }),
    ]);
    console.log("Logged in");
    await page.screenshot({
      path: "public/error/step2_logged_in.png",
      fullPage: true,
    });

    // === 2. Aller sur le profil ===
    await page.goto(profileUrl, {
      waitUntil: "domcontentloaded",
      timeout: 60000,
    });
    await page.waitForSelector("h1", { timeout: 60000 });
    console.log("Profile page loaded");
    await page.screenshot({
      path: "public/error/step3_profile_loaded.png",
      fullPage: true,
    });

    // Scroll pour charger contenu lazy
    await page.evaluate(() => window.scrollBy(0, window.innerHeight));
    await page.waitForTimeout(2000);
    await page.screenshot({
      path: "public/error/step4_scrolled.png",
      fullPage: true,
    });

    // === 3. Extraire les infos ===
    const profileData = await page.evaluate(() => {
      const getText = (selector) =>
        document.querySelector(selector)?.innerText || null;
      const getAllText = (selector) =>
        Array.from(document.querySelectorAll(selector)).map((el) =>
          el.innerText.trim()
        );

      return {
        name: getText("h1"),
        // headline: getText(""),
        location: getText("span"),
        // about: getText(""),
        // experiences: getAllText(
        //   ""
        // ),
        // education: getAllText(""),
        // skills: getAllText(""),
      };
    });

    await page.screenshot({
      path: "public/error/step5_data_extracted.png",
      fullPage: true,
    });

    console.log("Data extracted:", profileData);

    await browser.close();
    return profileData;
  } catch (err) {
    console.error("❌ Erreur pendant le scraping:", err.message);
    await page.screenshot({ path: "public/error/error.png", fullPage: true });
    await browser.close();
    throw err;
  }
};

module.exports = {
  authenticateUser,
  handleCallback,
  getUserProfile,
  scrapeLinkedInProfile,
};
