text: const express = require("express");
  const router = express.Router();
  const { check, validationResult } = require("express-validator");
  const axios = require("axios");
  const config = require("config");
  const normalize = require("normalize-url");
  
  const auth = require("../../middleware/auth");
  const Profile = require("../../models/Profile");
  const User = require("../../models/User");
  const Post = require("../../models/Post");
  
  // @route   GET api/profile/me
  // @desc    Get current user's profile
  // @access  Private
  router.get("/me", auth, async (req, res) => {
    try {
      let profile = await Profile.findOne({ user: req.user.id }).populate(
        "user",
        ["name", "avatar"]
      );
  
      if (!profile) {
        return res.status(400).json({ msg: "No profile found for this user." });
      }
  
      res.json(profile);
    } catch (err) {
      console.error(err.message);
      res.status(500).send("Internal Server Error.");
    }
  });
  
  // @route POST api/profile
  // @desc Create or update user profile
  // @access Private
  router.post(
    "/",
    [
      auth,
      [
        check("status", "Status is required").not().isEmpty(),
        check("skills", "Skills are required").not().isEmpty()
      ]
    ],
    async (req, res) => {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }
  
      const {
        company,
        website,
        location,
        bio,
        status,
        githubusername,
        skills,
        youtube,
        facebook,
        twitter,
        linkedin,
        instagram
      } = req.body;
  
      // Initialize & build the profile object
      const profileFields = {};
  
      profileFields.user = req.user.id;
  
      if (company) profileFields.company = company;
      if (website)
        profileFields.website = normalize(website, { forceHttps: true });
      if (location) profileFields.location = location;
      if (bio) profileFields.bio = bio;
      if (githubusername) profileFields.githubusername = githubusername;
      if (status) profileFields.status = status;
      if (skills) {
        profileFields.skills = skills.split(",").map((skill) => skill.trim());
      }
  
      // Initialize the social property of the profileFields
      profileFields.social = {};
  
      if (youtube)
        profileFields.social.youtube = normalize(youtube, { forceHttps: true });
      if (facebook)
        profileFields.social.facebook = normalize(facebook, { forceHttps: true });
      if (twitter)
        profileFields.social.twitter = normalize(twitter, { forceHttps: true });
      if (linkedin)
        profileFields.social.linkedin = normalize(linkedin, { forceHttps: true });
      if (instagram)
        profileFields.social.instagram = normalize(instagram, {
          forceHttps: true
        });
  
      try {
        let profile = await Profile.findOne({ user: req.user.id });
  
        if (profile) {
          // Update the existing profile
  
          profile = await Profile.findOneAndUpdate(
            { user: req.user.id },
            { $set: profileFields },
            { new: true, upsert: true }
          );
          return res.json(profile);
        }
  
        // Create a new profile
  
        profile = new Profile(profileFields);
  
        await profile.save();
  
        res.json(profile);
      } catch (err) {
        console.error(err.message);
        res.status(500).send("Internal Server Error");
      }
    }
  );
  
  // @route GET api/profile
  // @desc  Get all profiles
  // access Public
  router.get("/", async (req, res) => {
    try {
      const profiles = await Profile.find().populate("user", ["name", "avatar"]);
      res.json(profiles);
    } catch (err) {
      console.error(err.message);
      res.status(500).send("Internal Server Error");
    }
  });
  
  // @route GET api/profile/user/:user_id
  // @desc Get profile by user ID
  // access Public
  router.get("/user/:user_id", async (req, res) => {
    try {
      const profile = await Profile.findOne({
        user: req.params.user_id
      }).populate("user", ["name", "avatar"]);
  
      if (!profile) {
        return res.status(400).json({ msg: "Profile not found" });
      }
  
      res.json(profile);
    } catch (err) {
      console.error(err.message);
  
      if (err.kind == "ObjectId") {
        return res.status(400).json({ msg: "Profile not found" });
      }
  
      res.status(500).send("Internal Server Error");
    }
  });
  
  // @route DELETE api/profile
  // @desc Delete profile, user & posts
  // @access Private
  router.delete("/", auth, async (req, res) => {
    try {
      // Delete user posts
      await Post.deleteMany({ user: req.user.id });
      // Remove profile
      await Profile.findOneAndRemove({ user: req.user.id });
      // Remove user
      await User.findOneAndRemove({ _id: req.user.id });
  
      res.json({ msg: "User Deleted" });
    } catch (err) {
      console.error(err.message);
      res.status(500).send("Internal Server Error");
    }
  });
  
  // @route PUT api/profile/experience
  // @desc Add profile experience
  // access Private
  router.put(
    "/experience",
    [
      auth,
      [
        check("title", "Title is required").not().isEmpty(),
        check("company", "Company name is required").not().isEmpty(),
        check("from", "From date is required and must be from the past")
          .not()
          .isEmpty()
          .custom((value, { req }) => (req.body.to ? value < req.body.to : true))
      ]
    ],
    async (req, res) => {
      const errors = validationResult(req);
  
      if (!errors.isEmpty()) {
        return res.status(400).json({ msg: errors.array() });
      }
  
      const {
        title,
        company,
        location,
        from,
        to,
        current,
        description
      } = req.body;
  
      const newExp = { title, company, location, from, to, current, description };
  
      try {
        let profile = await Profile.findOne({ user: req.user.id });
  
        profile.experience.unshift(newExp);
        // unshift pushes the item to the beginning of an array
  
        await profile.save();
  
        res.json(profile);
      } catch (err) {
        console.error(err.message);
        res.status(500).send("Internal Server Error");
      }
    }
  );
  
  // @route DELETE api/profile/experience/:exp_id
  // @desc Delete experience from profile
  // access Private
  router.delete("/experience/:exp_id", auth, async (req, res) => {
    try {
      let foundProfile = await Profile.findOne({ user: req.user.id });
  
      foundProfile.experience = foundProfile.experience.filter(
        (exp) => exp._id.toString() !== req.params.exp_id
      );
  
      await foundProfile.save();
  
      return res.status(200).json(foundProfile);
    } catch (err) {
      console.error(err);
      res.status(500).json({ msg: "Internal Server Error" });
    }
  });
  
  // @route PUT api/profile/education
  // @desc Add profile education
  // access Private
  router.put(
    "/education",
    [
      auth,
      [
        check("school", "School is required").not().isEmpty(),
        check("degree", "Degree is required").not().isEmpty(),
        check("fieldofstudy", "Field of Study is required").not().isEmpty(),
        check("from", "From date is required and must be from the past")
          .not()
          .isEmpty()
          .custom((value, { req }) => (req.body.to ? value < req.body.to : true))
      ]
    ],
    async (req, res) => {
      const errors = validationResult(req);
  
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }
  
      const {
        school,
        degree,
        fieldofstudy,
        from,
        to,
        current,
        description
      } = req.body;
  
      const newEdu = {
        school,
        degree,
        fieldofstudy,
        from,
        to,
        current,
        description
      };
  
      try {
        let profile = await Profile.findOne({ user: req.user.id });
  
        profile.education.unshift(newEdu);
  
        await profile.save();
  
        res.json(profile);
      } catch (err) {
        console.error(err.message);
        res.status(500).send("Internal Server Error");
      }
    }
  );
  
  // @route DELETE api/profile/education/:edu_id
  // @desc Delete profile education
  // @access Private
  router.delete("/education/:edu_id", auth, async (req, res) => {
    try {
      let foundProfile = await Profile.findOne({ user: req.user.id });
  
      foundProfile.education = foundProfile.education.filter(
        (edu) => edu._id.toString() !== req.params.edu_id
      );
  
      await foundProfile.save();
  
      return res.status(200).json(foundProfile);
    } catch (err) {
      console.error(err.message);
      res.status(500).send("Internal Server Error");
    }
  });
  
  // @route GET api/profile/github/:username
  // @desc Get user repos from Github
  // @access Public
  router.get("/github/:username", async (req, res) => {
    try {
      const uri = encodeURI(
        `https://api.github.com/users/${req.params.username}/repos?per_page=5&sort=created:asc`
      );
  
      const headers = {
        "user-agent": "node.js",
        Authorization: `token ${config.get("githubToken")}`
      };
  
      const githubResponse = await axios.get(uri, { headers });
  
      return res.json(githubResponse.data);
    } catch (err) {
      console.error(err.message);
      res.status(404).json({ msg: "No Github profile found" });
    }
  });
  
  module.exports = router;
  