const { PermitToWork, Projects } = require("../models");
const { addFormattedIds, addFormattedId } = require("../utils/idFormatter");
const uploadFile = require("../utils/uploadFile");

/** Sequelize JSON may return object or string; API may send stringified JSON */
function normalizeAiAnalysis(value) {
  if (value == null) return null;
  if (typeof value === "object") return value;
  if (typeof value === "string") {
    try {
      return JSON.parse(value);
    } catch {
      return null;
    }
  }
  return null;
}

/**
 * AI Analysis endpoint using OpenRouter DeepSeek
 * POST /api/permit-to-work/analyze
 */
const analyzePermit = async (req, res) => {
  try {
    if (!process.env.OPENROUTER_API_KEY) {
      return res.status(503).json({
        success: false,
        message: "AI analysis is not configured (OPENROUTER_API_KEY)",
      });
    }

    const { permitType, workDescription, location, answers } = req.body;

    // Create a detailed prompt for the AI
    const systemPrompt = `You are an ISO 45001:2018 certified safety expert analyzing permit to work requests. 
Analyze the work details and provide a comprehensive safety assessment in JSON format.

Return ONLY valid JSON with this exact structure:
{
  "risk": "Low|Medium|High|Critical",
  "type": "Permit type name",
  "gasTest": true|false,
  "loto": true|false,
  "hazards": ["hazard1", "hazard2", ...],
  "controls": ["control1", "control2", ...],
  "ppe": ["ppe1", "ppe2", ...],
  "iso": ["ISO clause1", "ISO clause2", ...],
  "extra": ["additional permit1", ...]
}`;

    const userPrompt = `Analyze this permit to work request:

Work Type: ${permitType}
Description: ${workDescription}
Location: ${location}
Safety Answers: ${JSON.stringify(answers)}

Provide:
1. Risk level (Low/Medium/High/Critical)
2. Specific permit type name
3. Whether gas testing is required (true/false)
4. Whether LOTO is required (true/false)
5. List of 3-5 specific hazards
6. List of 4-6 control measures
7. List of 4-6 required PPE items
8. List of 2-4 applicable ISO 45001 clauses (format: "Cl. X.X.X — Description")
9. List of any additional permits required (0-3 items)

Return ONLY the JSON object, no other text.`;

    // Call OpenRouter API
    const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${process.env.OPENROUTER_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        model: "deepseek/deepseek-chat:free",
        messages: [
          {
            role: "system",
            content: systemPrompt
          },
          {
            role: "user",
            content: userPrompt
          }
        ],
        temperature: 0.3,
        max_tokens: 1000,
      })
    });

    const data = await response.json();

    if (!response.ok) {
      const msg = data?.error?.message || data?.message || "OpenRouter request failed";
      throw new Error(msg);
    }

    if (!data.choices || !data.choices[0]) {
      throw new Error("Invalid AI response");
    }

    const aiContent = data.choices[0].message.content;
    
    // Try to parse the AI response as JSON
    let analysis;
    try {
      // Remove markdown code blocks if present
      const cleanContent = aiContent.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim();
      analysis = JSON.parse(cleanContent);
    } catch (parseError) {
      console.error("Failed to parse AI response:", aiContent);
      // Fallback to default analysis based on permit type
      analysis = getFallbackAnalysis(permitType);
    }

    res.json({
      success: true,
      analysis,
      message: "AI analysis completed successfully",
    });
  } catch (err) {
    console.error("Error analyzing permit:", err);
    
    // Return fallback analysis on error
    const fallbackAnalysis = getFallbackAnalysis(req.body.permitType || "general");
    res.json({
      success: true,
      analysis: fallbackAnalysis,
      message: "Analysis completed (fallback mode)",
    });
  }
};

// Fallback analysis function
const getFallbackAnalysis = (permitType) => {
  const analysisResults = {
    "hot-work": {
      risk: "High",
      type: "Hot Work Permit — Class A",
      gasTest: true,
      loto: false,
      hazards: [
        "Fire or explosion from sparks",
        "Skin burns from extreme heat",
        "Harmful gas fumes",
        "Ignition of nearby materials",
      ],
      controls: [
        "Isolate 10m area with fire-resistant barriers",
        "Gas testing before start and every 2 hours",
        "Provide 9kg CO2 fire extinguisher",
        "Fire watch throughout work period",
      ],
      ppe: [
        "Helmet",
        "Heat-resistant gloves",
        "Face shield",
        "Welding apron",
        "Safety boots",
      ],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Operational controls",
        "Cl. 8.1.4 — REACH",
      ],
      extra: ["Fire Watch Permit", "Gas Test Certificate"],
    },
    "height": {
      risk: "High",
      type: "Working at Height Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Fall from height",
        "Falling tools on workers",
        "Scaffold collapse",
        "Fatigue and dizziness",
      ],
      controls: [
        "Inspect scaffold daily before use",
        "Wear safety harness and secure it",
        "Fall prevention net",
        "Restrict access below work area",
      ],
      ppe: ["Helmet", "Full body harness", "Non-slip boots", "Gloves"],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Operational controls",
      ],
      extra: ["Scaffold Inspection Certificate"],
    },
    "electrical": {
      risk: "Critical",
      type: "Electrical Safe Work Permit — HV",
      gasTest: false,
      loto: true,
      hazards: [
        "Electric shock",
        "Burns from electric arc",
        "Distribution panel explosion",
        "Electrical fire",
      ],
      controls: [
        "Apply full LOTO procedure",
        "Verify no voltage with measuring device",
        "Use 1000V insulated tools",
        "Licensed electrician Class 4 present",
      ],
      ppe: [
        "Class 4 electrical insulation gloves",
        "Helmet with face shield",
        "Arc-resistant suit",
        "Insulated boots",
      ],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — LOTO",
        "Cl. 8.1.4 — Hazardous energy",
      ],
      extra: ["LOTO Certificate", "HV Authorization Form"],
    },
    "confined": {
      risk: "Critical",
      type: "Confined Space Entry Permit",
      gasTest: true,
      loto: true,
      hazards: [
        "Oxygen deficiency",
        "Toxic gas accumulation",
        "Collapse and suffocation",
        "Emergency rescue difficulty",
      ],
      controls: [
        "Gas testing: O2/CO/H2S/LEL",
        "Forced ventilation 20 minutes before entry",
        "Entry guard outside space at all times",
        "Rescue plan ready and rescue team present",
      ],
      ppe: [
        "SCBA self-contained breathing apparatus",
        "Rescue harness",
        "Personal gas detector",
        "Helmet",
        "Rubber boots",
      ],
      iso: [
        "Cl. 6.1.2 — Confined Space",
        "Cl. 8.1.1 — Entry controls",
        "Cl. 8.2 — Emergency preparedness",
      ],
      extra: ["Gas Test Certificate", "Rescue Plan Approval"],
    },
    "lifting": {
      risk: "Medium",
      type: "Lifting Operations Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Load falling on people",
        "Crane collapse",
        "Collision with infrastructure",
        "Overload",
      ],
      controls: [
        "Check crane certificate and validity",
        "Calculate load weight accurately before start",
        "Define and evacuate work area",
        "Continuous coordination with crane operator",
      ],
      ppe: ["Helmet", "Reflective vest", "Gloves", "Safety boots"],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Lifting controls",
      ],
      extra: ["Crane Operator Certificate", "Load Test Certificate"],
    },
    "general": {
      risk: "Low",
      type: "General Work Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Slips and falls",
        "Mechanical injuries",
        "Excessive noise",
        "Heat stress",
      ],
      controls: [
        "Clean work area before start",
        "Use appropriate and safe tools",
        "Regular breaks every 2 hours",
        "Drink adequate amounts of water",
      ],
      ppe: ["Helmet", "Gloves", "Safety boots", "Reflective vest"],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Operational controls",
      ],
      extra: [],
    },
    "high-voltage": {
      risk: "Critical",
      type: "High Voltage Work Permit",
      gasTest: false,
      loto: true,
      hazards: [
        "Electric shock from high voltage",
        "Arc flash burns",
        "Electrocution",
        "Equipment explosion",
      ],
      controls: [
        "Complete LOTO and verify zero voltage",
        "Maintain safe distance from live equipment",
        "Use voltage testing equipment",
        "Establish safety zones with barriers",
      ],
      ppe: [
        "Arc-rated suit",
        "Insulated gloves (rated for voltage)",
        "Face shield",
        "Insulated boots",
        "Voltage detector",
      ],
      iso: [
        "Cl. 8.1.1 — Electrical Safety",
        "Cl. 8.1.4 — Hazardous energy",
        "Cl. 8.2 — Emergency preparedness",
      ],
      extra: ["High Voltage Authorization", "LOTO Certificate"],
    },
    "public-area": {
      risk: "Medium",
      type: "Public Area Construction Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Pedestrian injuries",
        "Vehicle collisions",
        "Falling objects on public",
        "Noise and dust complaints",
      ],
      controls: [
        "Install barriers and safety fencing",
        "Assign traffic control personnel",
        "Overhead protection for walkways",
        "Monitor noise and dust levels",
      ],
      ppe: ["Helmet", "Reflective vest", "Safety boots", "Gloves"],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Public safety controls",
      ],
      extra: ["Traffic Management Plan", "Public Notification"],
    },
    "blasting": {
      risk: "Critical",
      type: "Rock Blasting Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Explosion injuries",
        "Flying rock fragments",
        "Ground vibration damage",
        "Noise-induced hearing loss",
      ],
      controls: [
        "Establish blast exclusion zone",
        "Check weather conditions",
        "Secure explosives storage",
        "Monitor vibration levels",
      ],
      ppe: [
        "Helmet",
        "Hearing protection",
        "Safety glasses",
        "Dust mask",
        "Safety boots",
      ],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Blasting controls",
        "Cl. 8.2 — Emergency preparedness",
      ],
      extra: ["Blasting License", "Vibration Monitoring Plan"],
    },
    "excavation": {
      risk: "High",
      type: "Excavation Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Trench collapse",
        "Underground utility strikes",
        "Equipment rollover",
        "Falling into excavation",
      ],
      controls: [
        "Identify underground utilities before digging",
        "Install shoring or sloping",
        "Barricade excavation perimeter",
        "Inspect soil stability daily",
      ],
      ppe: [
        "Helmet",
        "Reflective vest",
        "Safety boots",
        "Gloves",
        "Dust mask",
      ],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Excavation controls",
      ],
      extra: ["Utility Location Certificate", "Soil Stability Report"],
    },
    "concrete": {
      risk: "Medium",
      type: "Concrete Work Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Chemical burns from wet concrete",
        "Musculoskeletal injuries from lifting",
        "Formwork collapse",
        "Vibration exposure",
      ],
      controls: [
        "Inspect formwork stability",
        "Provide eyewash stations",
        "Use mechanical aids for heavy lifting",
        "Take regular breaks from vibration tools",
      ],
      ppe: [
        "Helmet",
        "Chemical-resistant gloves",
        "Safety glasses",
        "Waterproof boots",
        "Knee pads",
      ],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.1 — Concrete safety",
        "Cl. 8.1.4 — Chemical exposure",
      ],
      extra: ["Formwork Inspection Certificate"],
    },
    "dust-handling": {
      risk: "Medium",
      type: "Dust Handling Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Respiratory diseases from dust inhalation",
        "Eye irritation",
        "Skin irritation",
        "Reduced visibility",
      ],
      controls: [
        "Install ventilation and dust collectors",
        "Use wet methods to suppress dust",
        "Monitor air quality regularly",
        "Delimit work area to contain dust",
      ],
      ppe: [
        "P3 respirator",
        "Safety glasses",
        "Gloves",
        "Covering clothing",
        "Safety boots",
      ],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.4 — Dust exposure",
      ],
      extra: ["Air Quality Monitoring Report"],
    },
    "hazardous-chemicals": {
      risk: "Critical",
      type: "Hazardous Chemical Handling Permit",
      gasTest: false,
      loto: false,
      hazards: [
        "Chemical burns from acid/base contact",
        "Toxic fumes inhalation",
        "Fire or explosion from reactive chemicals",
        "Environmental contamination from spills",
      ],
      controls: [
        "Ensure proper ventilation systems active",
        "Segregate incompatible chemicals",
        "Spill containment procedures in place",
        "Emergency eyewash and shower accessible",
      ],
      ppe: [
        "Chemical-resistant gloves",
        "Face shield or goggles",
        "Respirator with appropriate filters",
        "Chemical-resistant apron",
        "Chemical-resistant boots",
      ],
      iso: [
        "Cl. 6.1.2 — Hazard identification",
        "Cl. 8.1.4 — Hazardous substances",
        "Cl. 8.2 — Emergency preparedness",
      ],
      extra: ["SDS Review Certificate", "Spill Response Plan"],
    },
  };

  return analysisResults[permitType] || analysisResults["general"];
};

/**
 * Get all Permits to Work (or single permit if editId provided)
 * GET /api/permit-to-work
 */
const getPermitsToWork = async (req, res) => {
  const { projectId, editId } = req.query;

  try {
    // If editId is provided, return single permit
    if (editId) {
      const permit = await PermitToWork.findByPk(editId, {
        include: [Projects],
      });

      if (!permit) {
        return res.status(404).json({ message: "Permit to work not found" });
      }

      let parsedData;
      try {
        parsedData = JSON.parse(permit.data || "{}");
        
        // Check if data was double-stringified
        if (typeof parsedData === 'string') {
          parsedData = JSON.parse(parsedData);
        }
      } catch (err) {
        console.error("Error parsing permit data:", err);
        parsedData = {};
      }

      const responseData = {
        ...parsedData,
        id: permit.id,
        project: permit.Project.name,
        status: permit.status,
        aiAnalysis: normalizeAiAnalysis(permit.aiAnalysis),
        createdAt: permit.createdAt,
      };

      const response = {
        data: addFormattedId("permit-to-work", responseData),
      };

      return res.json(response);
    }

    // Otherwise return all permits for the project
    const permits = await PermitToWork.findAll({
      where: {
        ProjectId: projectId,
      },
      include: [Projects],
      order: [["createdAt", "DESC"]],
    });

    const response = permits.map(({ data, Project, id, status, aiAnalysis, createdAt }) => {
      let parsedData;
      try {
        parsedData = JSON.parse(data || "{}");
        
        // Check if data was double-stringified (if parsedData is a string, parse again)
        if (typeof parsedData === 'string') {
          parsedData = JSON.parse(parsedData);
        }
      } catch (err) {
        console.error("Error parsing permit data:", err);
        parsedData = {};
      }

      return {
        ...parsedData,
        id,
        project: Project.name,
        status,
        aiAnalysis: normalizeAiAnalysis(aiAnalysis),
        createdAt,
      };
    });

    res.json(addFormattedIds("permit-to-work", response));
  } catch (err) {
    console.error("Error fetching permits:", err);
    res.status(500).json({ message: "Failed to fetch permits" });
  }
};

/**
 * Get single Permit to Work
 * GET /api/permit-to-work/:id
 */
const getSinglePermitToWork = async (req, res) => {
  const { id } = req.params;

  try {
    const permit = await PermitToWork.findByPk(id, {
      include: [Projects],
    });

    if (!permit) {
      return res.status(404).json({ message: "Permit to work not found" });
    }

    let parsedData;
    try {
      parsedData = JSON.parse(permit.data || "{}");
      
      // Check if data was double-stringified
      if (typeof parsedData === 'string') {
        parsedData = JSON.parse(parsedData);
      }
    } catch (err) {
      console.error("Error parsing permit data:", err);
      parsedData = {};
    }

    const responseData = {
      ...parsedData,
      id: permit.id,
      project: permit.Project.name,
      status: permit.status,
      aiAnalysis: permit.aiAnalysis ? JSON.parse(permit.aiAnalysis) : null,
      createdAt: permit.createdAt,
    };

    const response = {
      data: addFormattedId("permit-to-work", responseData),
    };

    res.json(response);
  } catch (err) {
    console.error("Error fetching permit:", err);
    res.status(500).json({ message: "Failed to fetch permit" });
  }
};

/**
 * Create new Permit to Work
 * POST /api/permit-to-work
 */
const createPermitToWork = async (req, res) => {
  const { projectId } = req.query;

  if (!projectId)
    return res.status(400).json({ message: "Project id is required" });

  try {
    // Check if data is sent as JSON or form data
    let dataToStore, aiAnalysisToStore;
    
    if (req.body.data) {
      // Data is already stringified from frontend, use it directly
      dataToStore = req.body.data;
      aiAnalysisToStore = req.body.aiAnalysis ?? null;
    } else if (req.files) {
      // Data sent as form data with files
      const filesData = await uploadFile(req.files);
      const parsedData = JSON.parse(req.body.data || '{}');
      dataToStore = JSON.stringify({ ...parsedData, ...filesData });
      aiAnalysisToStore = req.body.aiAnalysis || null;
    } else {
      return res.status(400).json({ message: "No data provided" });
    }

    const createdPermit = await PermitToWork.create({
      data: dataToStore,
      aiAnalysis: aiAnalysisToStore,
      status: "pending",
      ProjectId: projectId,
    });

    // Get formatted ID
    const formattedData = addFormattedId("permit-to-work", {
      id: createdPermit.id,
    });

    res.status(201).json({
      message: "Permit to work created successfully",
      permitId: formattedData.formattedId,
      id: createdPermit.id,
    });
  } catch (err) {
    console.error("Error creating permit:", err);
    res.status(500).json({ message: "Failed to create permit" });
  }
};

/**
 * Update Permit to Work status
 * PATCH /api/permit-to-work/:id/status
 */
const updatePermitStatus = async (req, res) => {
  const { id } = req.params;
  const { status } = req.body;

  if (!["pending", "approved", "rejected"].includes(status)) {
    return res.status(400).json({ message: "Invalid status value" });
  }

  try {
    const permit = await PermitToWork.findByPk(id);

    if (!permit) {
      return res.status(404).json({ message: "Permit to work not found" });
    }

    await permit.update({ status });

    res.json({
      message: `Permit ${status} successfully`,
      status: permit.status,
    });
  } catch (err) {
    console.error("Error updating permit status:", err);
    res.status(500).json({ message: "Failed to update permit status" });
  }
};

/**
 * Update Permit to Work
 * PUT /api/permit-to-work/:id
 * PATCH /api/permit-to-work?editId=X
 */
const updatePermitToWork = async (req, res) => {
  // Support both :id param and editId query param
  const id = req.params.id || req.query.editId;

  console.log("=== UPDATE PTW DEBUG ===");
  console.log("ID:", id);
  console.log("req.body:", req.body);
  console.log("req.files:", req.files);

  if (!id) {
    return res.status(400).json({ message: "Permit ID is required" });
  }

  try {
    const permit = await PermitToWork.findByPk(id);

    console.log("Permit found:", permit);
    console.log("Permit type:", typeof permit);
    console.log("Permit is null?", permit === null);
    console.log("Permit methods:", permit ? Object.getOwnPropertyNames(Object.getPrototypeOf(permit)) : "N/A");

    if (!permit) {
      return res.status(404).json({ message: "Permit to work not found" });
    }

    console.log("Existing permit data:", permit.data);

    let dataToUpdate;
    
    // Parse existing data
    let existingData = {};
    try {
      existingData = JSON.parse(permit.data || "{}");
      // Handle double-stringified data
      if (typeof existingData === 'string') {
        existingData = JSON.parse(existingData);
      }
    } catch (err) {
      console.error("Error parsing existing data:", err);
    }

    if (req.files) {
      const filesData = await uploadFile(req.files);
      dataToUpdate = { ...existingData, ...req.body, ...filesData };
    } else {
      // Merge new data with existing data
      dataToUpdate = { ...existingData, ...req.body };
    }

    // If responsiblePerson is a number (user ID), convert it to user name
    if (dataToUpdate.responsiblePerson && typeof dataToUpdate.responsiblePerson === 'number') {
      try {
        const { Users } = require("../models");
        const user = await Users.findByPk(dataToUpdate.responsiblePerson);
        if (user) {
          dataToUpdate.responsiblePerson = user.fullname;
        }
      } catch (err) {
        console.error("Error fetching user name:", err);
      }
    }

    // Use Sequelize's static update method
    await PermitToWork.update(
      {
        data: JSON.stringify(dataToUpdate),
      },
      {
        where: { id: id },
      }
    );

    res.json({
      message: "Permit to work updated successfully",
    });
  } catch (err) {
    console.error("Error updating permit:", err);
    console.error("Error stack:", err.stack);
    res.status(500).json({ message: "Failed to update permit", error: err.message });
  }
};

module.exports = {
  analyzePermit,
  getPermitsToWork,
  getSinglePermitToWork,
  createPermitToWork,
  updatePermitStatus,
  updatePermitToWork,
};
