﻿
import { Request, Response } from 'express';
import { WorkOrder } from '../models/WorkOrder';
import { findProjectByIdOrCode } from '../utils/projectHelper';
import { createWorkOrderAlert } from '../services/alertService';
import mongoose from 'mongoose';
import { buildWorkOrderWebhookPayload, sendCsmWebhookSafely } from '../services/csmWebhookClient';

export const getWorkOrders = async (req: Request, res: Response) => {
    try {
        const { projectId } = req.query;

        if (!projectId) {
            return res.status(400).json({ success: false, message: 'projectId is required' });
        }

        // Handle both ObjectId and string ID
        let projectObjectId: any;

        // Check if projectId is a valid MongoDB ObjectId
        if (mongoose.Types.ObjectId.isValid(projectId as string)) {
            projectObjectId = new mongoose.Types.ObjectId(projectId as string);
        } else {
            // Use helper function to find project without Mongoose casting errors
            const project = await findProjectByIdOrCode(projectId as string);
            if (!project) {
                return res.status(404).json({ success: false, message: `Project with ID or code "${projectId}" not found` });
            }
            projectObjectId = project._id;
        }

        // Query for both ObjectId and string versions of projectId to handle mixed storage
        const objectIdProjectId = mongoose.Types.ObjectId.isValid(projectObjectId)
            ? new mongoose.Types.ObjectId(projectObjectId)
            : null;
        const stringProjectId = projectObjectId.toString();

        const workOrders = await WorkOrder.find({
            $or: [
                { projectId: projectObjectId },
                { projectId: stringProjectId },
                ...(objectIdProjectId ? [{ projectId: objectIdProjectId }] : [])
            ]
        }).sort({ createdAt: -1 });

        res.json({
            success: true,
            data: workOrders
        });
    } catch (error: any) {
        res.status(500).json({ success: false, message: error.message });
    }
};

export const createWorkOrder = async (req: Request, res: Response) => {
    try {
        const workOrderData = req.body;

        // Map legacy 'type' to 'workOrderType' if needed
        if (workOrderData.type && !workOrderData.workOrderType) {
            workOrderData.workOrderType = workOrderData.type;
        }

        // Ensure projectId is set (frontend might send siteId)
        if (!workOrderData.projectId && workOrderData.siteId) {
            workOrderData.projectId = workOrderData.siteId;
        }

        // Basic validation
        if (!workOrderData.projectId || !workOrderData.title) {
            return res.status(400).json({
                success: false,
                message: 'Missing required fields: projectId, assetId, title'
            });
        }

        const newWorkOrder = new WorkOrder(workOrderData);
        await newWorkOrder.save();

        // Create alert if work order is assigned or has deadline
        if (newWorkOrder.assignedTechnicianId || newWorkOrder.assignedTo) {
            await createWorkOrderAlert(
                newWorkOrder.woCode,
                newWorkOrder._id.toString(),
                'Work order mới được giao cho bạn',
                'Info'
            );
        }

        if (newWorkOrder.scheduledEnd) {
            const deadline = new Date(newWorkOrder.scheduledEnd);
            const now = new Date();
            const hoursUntilDeadline = (deadline.getTime() - now.getTime()) / (1000 * 60 * 60);
            
            if (hoursUntilDeadline <= 24 && hoursUntilDeadline > 0) {
                await createWorkOrderAlert(
                    newWorkOrder.woCode,
                    newWorkOrder._id.toString(),
                    `Sắp đến hạn hoàn thành (Còn ${Math.ceil(hoursUntilDeadline)} giờ)`,
                    hoursUntilDeadline <= 8 ? 'Critical' : 'Warning'
                );
            }
        }

        res.status(201).json({
            success: true,
            data: newWorkOrder,
            message: 'Work order created successfully'
        });
    } catch (error: any) {
        console.error('Error creating work order:', error);
        res.status(500).json({ success: false, message: error.message });
    }
};

export const updateWorkOrder = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        const updateData = req.body;

        // Map legacy 'type' to 'workOrderType' if needed
        if (updateData.type && !updateData.workOrderType) {
            updateData.workOrderType = updateData.type;
        }

        delete updateData._id; // Don't update _id

        const oldWorkOrder = await WorkOrder.findById(id).lean();

        const updatedWorkOrder = await WorkOrder.findByIdAndUpdate(
            id,
            updateData,
            { new: true } // Return updated document
        );

        if (!updatedWorkOrder) {
            // Try to find by custom string ID if ObjectId lookup failed
            const workOrder = await WorkOrder.findOne({ _id: id });
            if (workOrder) {
                Object.assign(workOrder, updateData);
                await workOrder.save();
                return res.json({
                    success: true,
                    data: workOrder,
                    message: 'Work order updated successfully'
                });
            }

            return res.status(404).json({ success: false, message: 'Work order not found' });
        }

        const changedFields = ['status', 'assignedTechnicianId', 'assignedTo', 'scheduledStart', 'scheduledEnd', 'checklistProgress'].filter((field) => {
            const before = (oldWorkOrder as any)?.[field];
            const after = (updatedWorkOrder as any)?.[field];
            return String(before ?? '') !== String(after ?? '');
        });
        if (changedFields.length > 0) {
            await sendCsmWebhookSafely(buildWorkOrderWebhookPayload(updatedWorkOrder, oldWorkOrder, changedFields));
        }

        res.json({
            success: true,
            data: updatedWorkOrder,
            message: 'Work order updated successfully'
        });
    } catch (error: any) {
        console.error('Error updating work order:', error);
        res.status(500).json({ success: false, message: error.message });
    }
};

export const deleteWorkOrder = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;

        // Support both string and ObjectId for lookup
        const query = {
            $or: [
                { _id: id },
                { _id: mongoose.Types.ObjectId.isValid(id) ? new mongoose.Types.ObjectId(id) : null }
            ].filter(f => f._id !== null)
        };

        const deletedWorkOrder = await WorkOrder.findOneAndDelete(query);

        if (!deletedWorkOrder) {
            return res.status(404).json({ success: false, message: 'Work order not found' });
        }

        res.json({
            success: true,
            message: 'Work order deleted successfully'
        });
    } catch (error: any) {
        console.error('Error deleting work order:', error);
        res.status(500).json({ success: false, message: error.message });
    }
};
