const { Op } = require("sequelize");
const { Reports, Companies } = require("../models");
const fetch = require("node-fetch");

const getChartData = async (req, res) => {
  const { projectId, type, year } = req.query;
  try {
    const startDate = new Date(`${year}-01-01T00:00:00.000Z`);
    const endDate = new Date(`${Number(year) + 1}-01-01T00:00:00.000Z`);

    const reports = await Reports.findAll({
      where: {
        ProjectId: projectId,
        type,
        createdAt: {
          [Op.gte]: startDate,
          [Op.lt]: endDate,
        },
      },
    });

    const addCount = (obj, date) => {
      obj[date] = (obj[date] || 0) + 1;
    };

    const typeKey =
      type == "deviations"
        ? "type_of_deviation"
        : type == "case-investigations"
        ? "type"
        : "";

    const tmpReportsMap = {};
    reports.forEach((report) => {
      const type = typeKey ? JSON.parse(report.data)[typeKey] : "";
      if (!tmpReportsMap[type]) tmpReportsMap[type] = [];
      tmpReportsMap[type].push(report);
    });

    const reportsMap = {};

    for (const type in tmpReportsMap) {
      if (Object.prototype.hasOwnProperty.call(tmpReportsMap, type)) {
        const items = {};
        tmpReportsMap[type].forEach((report) => {
          const date = `${new Date(report.createdAt).getFullYear()}/${new Date(
            report.createdAt
          ).getMonth()}`;
          addCount(items, date);
        });
        reportsMap[type] = items;
      }
    }

    res.json(reportsMap);
  } catch (err) {
    res.status(500).json({ message: "Failed to fetch" });
  }
};

const getHomeData = async (req, res) => {
  const { projectId } = req.query;
  try {
    const reports = await Reports.findAll({
      where: {
        ProjectId: projectId,
      },
    });

    res.json({
      deviations: reports.filter((report) => report.type == "deviations")
        .length,
      "site-monitoring": reports.filter(
        (report) => report.type == "site-monitoring"
      ).length,
      "case-investigations": reports.filter(
        (report) => report.type == "case-investigations"
      ).length,
    });
  } catch (err) {
    console.log(err.message);

    res.status(500).json({ message: "Failed to fetch" });
  }
};

const getCompanyName = async (req, res) => {
  const { orgNumber } = req.body;
  try {
    const brregRes = await fetch(
      `https://data.brreg.no/enhetsregisteret/api/enheter/${orgNumber}`,
    );
    if (!brregRes.ok) {
      throw new Error(`Brreg HTTP ${brregRes.status}`);
    }
    const data = await brregRes.json();
    return res.json({
      name: data.navn || "",
      email: data.epostadresse || "",
      phoneNumber: data.telefon || "",
    });
  } catch (err) {
    return res.status(500).json({
      message: "Failed to fetch company name",
      err: err.message,
      name: "",
      email: "",
      phoneNumber: "",
    });
  }
};

const getSharepointInfo = async (req, res) => {
  try {
    const company = await Companies.findByPk(req.user.companyId);
    if (!company) {
      return res.status(404).json({ message: "Company not found" });
    }

    const sharepointInfo = {
      connected: company.msConnected,
      siteId: company.msSharepointSiteId,
      tenantId: company.tenantId,
      listMapping: company.spListMapping,
      // Provide access instructions
      accessInstructions: [
        "1. Go to https://www.office.com",
        "2. Sign in with your Microsoft account: " + req.user.email,
        "3. Click on 'SharePoint' from the app launcher",
        "4. Look for lists starting with 'NordSafe_'",
        "5. Check 'NordSafe_Deviations' list for your data"
      ]
    };

    res.json(sharepointInfo);
  } catch (error) {
    console.error("Error getting SharePoint info:", error);
    res.status(500).json({ message: "Failed to get SharePoint info" });
  }
};

const setupSharepointLists = async (req, res) => {
  try {
    const company = await Companies.findByPk(req.user.companyId);
    if (!company) {
      return res.status(404).json({ message: "Company not found" });
    }

    // Check if user is admin
    if (req.user.role !== 'admin') {
      return res.status(403).json({ message: "Only admins can setup SharePoint lists" });
    }

    // Get fresh access token
    const { ensureFreshMsAccessToken } = require("../utils/msTokenService");
    const accessToken = await ensureFreshMsAccessToken(req.user.companyId);
    
    if (!accessToken) {
      return res.status(400).json({ 
        message: "Microsoft account not connected. Please connect your Microsoft account first.",
        needsAuth: true
      });
    }

    // Run SharePoint setup
    const { setupCompanySharepoint } = require("../services/sharepoint");
    const result = await setupCompanySharepoint(req.user.companyId, accessToken, true);

    if (result.success) {
      return res.json({
        success: true,
        message: result.message,
        details: {
          createdLists: result.createdLists || [],
          failedLists: result.failedLists || [],
          missingLists: result.missingLists || [],
          siteId: result.siteId,
          listMapping: result.spListMapping
        }
      });
    } else {
      return res.status(500).json({
        success: false,
        message: "Failed to setup SharePoint lists",
        error: result.error
      });
    }
  } catch (error) {
    console.error("Error setting up SharePoint lists:", error);
    res.status(500).json({ 
      success: false,
      message: "Failed to setup SharePoint lists",
      error: error.message 
    });
  }
};

module.exports = { getChartData, getHomeData, getCompanyName, getSharepointInfo, setupSharepointLists };
