const { Companies } = require("../models");
const { getLists } = require("../services/microsoftGraph");
const { ensureFreshMsAccessToken } = require("../utils/msTokenService");
const { setupCompanySharepoint } = require("../services/sharepoint");

const CONFIG_KEYS = [
  "incidents",
  "riskAssessments",
  "jsa",
  "permitToWork",
  "hazop",
  "minutesOfMeeting",
  "sds",
];

function isMappingComplete(m) {
  if (!m || typeof m !== "object") return false;
  return CONFIG_KEYS.every((k) => m[k] != null && String(m[k]).trim() !== "");
}

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

    const needsSharepointConfig =
      !!company.msConnected && !isMappingComplete(company.spListMapping);

    res.json({
      needsSharepointConfig,
      msConnected: !!company.msConnected,
      hasMapping: isMappingComplete(company.spListMapping),
      spListMapping: company.spListMapping || null,
    });
  } catch (e) {
    console.error(e);
    res.status(500).json({ message: "Failed to load SharePoint status" });
  }
};

/**
 * GET /api/companies/sharepoint/lists
 */
const getSharepointLists = async (req, res) => {
  const allowed = ["admin", "super-admin"];
  if (!allowed.includes(req.user.role)) {
    return res.status(403).json({ message: "Forbidden" });
  }
  try {
    const company = await Companies.findByPk(req.user.companyId);
    if (!company?.msSharepointSiteId) {
      return res.status(400).json({ message: "SharePoint site not connected yet" });
    }
    const token = await ensureFreshMsAccessToken(company.id);
    if (!token) {
      return res.status(400).json({
        message: "Microsoft tokens missing or expired — sign in with Microsoft again",
      });
    }
    const lists = await getLists(token, company.msSharepointSiteId);
    res.json({ lists });
  } catch (e) {
    console.error(e);
    res.status(500).json({ message: e.message || "Failed to list SharePoint lists" });
  }
};

/**
 * POST /api/companies/sharepoint/mapping
 * body: { incidents?: listId, riskAssessments?: listId, ... }
 */
const saveSharepointMapping = async (req, res) => {
  const allowed = ["admin", "super-admin"];
  if (!allowed.includes(req.user.role)) {
    return res.status(403).json({ message: "Forbidden" });
  }
  try {
    const company = await Companies.findByPk(req.user.companyId);
    if (!company?.msConnected) {
      return res.status(400).json({ message: "SharePoint not connected" });
    }

    const payload = req.body || {};
    const next = { ...(company.spListMapping || {}) };

    for (const key of CONFIG_KEYS) {
      if (payload[key] !== undefined && payload[key] !== null && payload[key] !== "") {
        next[key] = String(payload[key]).trim();
      }
    }

    await Companies.update({ spListMapping: next }, { where: { id: company.id } });
    res.json({
      message: "SharePoint mapping saved",
      spListMapping: next,
      isComplete: isMappingComplete(next),
    });
  } catch (e) {
    console.error(e);
    res.status(500).json({ message: e.message || "Failed to save mapping" });
  }
};

/**
 * POST /api/companies/sharepoint/auto-create
 * Creates NordSafe lists via Graph and refreshes spListMapping.
 */
const autoCreateSharepointLists = async (req, res) => {
  const allowed = ["admin", "super-admin"];
  if (!allowed.includes(req.user.role)) {
    return res.status(403).json({ message: "Forbidden" });
  }
  try {
    const company = await Companies.findByPk(req.user.companyId);
    if (!company) {
      return res.status(404).json({ message: "Company not found" });
    }
    
    const token = await ensureFreshMsAccessToken(company.id);
    if (!token) {
      return res.status(400).json({ 
        message: "Microsoft tokens missing or expired. Please reconnect your Microsoft account.",
        needsAuth: true
      });
    }
    
    console.log(`🚀 Admin triggered SharePoint list creation for company ${company.id}`);
    
    // Get custom site URL from company record (if set)
    const customSiteUrl = company.msSharepointCustomSite || null;
    if (customSiteUrl) {
      console.log(`📍 Using custom SharePoint site: ${customSiteUrl}`);
    }
    
    // Use forceRecreate=true to attempt creating missing lists
    const result = await setupCompanySharepoint(company.id, token, true, false, customSiteUrl);
    
    if (!result.success) {
      return res.status(500).json({ 
        message: result.error || "SharePoint provisioning failed",
        error: result.error
      });
    }
    
    const updated = await Companies.findByPk(company.id);
    
    // Build response message
    let message = result.message || "SharePoint lists setup completed";
    
    if (result.createdLists && result.createdLists.length > 0) {
      message = `✅ Successfully created ${result.createdLists.length} SharePoint list(s)`;
    } else if (result.missingLists && result.missingLists.length > 0) {
      message = `⚠️ ${result.missingLists.length} list(s) need manual creation in SharePoint`;
    }
    
    res.json({
      success: true,
      message,
      spListMapping: updated.spListMapping,
      siteId: result.siteId,
      customSiteUrl: customSiteUrl,
      createdLists: result.createdLists || [],
      failedLists: result.failedLists || [],
      missingLists: result.missingLists || [],
      creationBlocked: result.creationBlocked || false,
    });
  } catch (e) {
    console.error("❌ Auto-create SharePoint lists error:", e);
    res.status(500).json({ 
      success: false,
      message: e.message || "Failed to create lists",
      error: e.message
    });
  }
};

module.exports = {
  getSharepointStatus,
  getSharepointLists,
  saveSharepointMapping,
  autoCreateSharepointLists,
  CONFIG_KEYS,
  isMappingComplete,
};
