const pool = require('../config/db');
const asyncHandler = require('../middlewares/asyncHandler');
const {
  getAllForms,
  getFormsExcludeArchived,
  getFormById,
  createForm,
  updateForm,
  deleteForm,
  insertFormLog,
  getFormLogsFromView
} = require('../repositories/formsRepository');

// Get all forms (includes archived; for View Forms page only)
exports.getAllForms = asyncHandler(async (req, res) => {
    const rows = await getAllForms();
    res.status(200).json({ success: true, data: rows });
});

// Get forms excluding archived (for Update Form dropdown and audit form selection)
exports.getFormsForSelection = asyncHandler(async (req, res) => {
    const rows = await getFormsExcludeArchived();
    res.status(200).json({ success: true, data: rows });
});

// GET form logs from sat_form_logs_view (for Forms Logs page). Query: limit (optional, default 500, max 1000)
exports.getFormLogs = asyncHandler(async (req, res) => {
    const limit = req.query.limit;
    const rows = await getFormLogsFromView(limit);
    res.status(200).json({ success: true, data: rows });
});

// Sub-API: insert one row into sat_form_logs (e.g. after update). Body: { form_id, user_id, action: 'UPDATED' }
exports.addFormLog = asyncHandler(async (req, res) => {
    const { form_id, user_id, action } = req.body;
    if (!form_id || !user_id || !action) {
        return res.status(400).json({ success: false, message: 'form_id, user_id, and action are required' });
    }
    if (action !== 'CREATED' && action !== 'UPDATED') {
        return res.status(400).json({ success: false, message: 'action must be CREATED or UPDATED' });
    }
    await insertFormLog(form_id, user_id, action, null);
    res.status(201).json({ success: true, message: 'Form log added', data: { form_id, user_id, action } });
});

// Get form by ID
exports.getFormById = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const form = await getFormById(id);
    
    if (!form) {
        return res.status(404).json({ success: false, message: 'Form not found' });
    }
    
    res.status(200).json({ success: true, data: form });
});

// Ensure location_ids is always an array of numbers (supports single value or comma-separated string from client)
const normalizeLocationIds = (locationIds) => {
    if (locationIds == null) return [];
    if (Array.isArray(locationIds)) {
        return locationIds.map(id => parseInt(id, 10)).filter(n => !isNaN(n));
    }
    if (typeof locationIds === 'string' && locationIds.trim() !== '') {
        return locationIds.split(',').map(s => parseInt(s.trim(), 10)).filter(n => !isNaN(n));
    }
    const n = parseInt(locationIds, 10);
    return isNaN(n) ? [] : [n];
};

// Create form
exports.createForm = asyncHandler(async (req, res) => {
    const { form_type_id, form_parent_id, title, description, created_by, created_date, end_date, question_ids, location_ids } = req.body;
    
    if (!form_type_id || !title || !created_by) {
        return res.status(400).json({ success: false, message: 'form_type_id, title, and created_by are required' });
    }
    
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        
        const formData = { form_type_id, form_parent_id, title, description, created_by, created_date, end_date };
        const normalizedLocationIds = normalizeLocationIds(location_ids);
        const formId = await createForm(formData, question_ids, normalizedLocationIds, connection);
        
        await connection.commit();
        res.status(201).json({ success: true, message: 'Form created successfully', data: { form_id: formId } });
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
});

// Update form (rejected for archived/parent forms). Non-question changes (e.g. location) are logged in sat_form_logs.
exports.updateForm = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const { form_type_id, form_parent_id, title, description, created_by, created_date, end_date, question_ids, location_ids, updated_by } = req.body;

    const form = await getFormById(id);
    if (!form) {
        return res.status(404).json({ success: false, message: 'Form not found' });
    }
    if (form.is_archived) {
        return res.status(403).json({ success: false, message: 'Parent (archived) forms cannot be updated. They are view-only.' });
    }

    const updateData = {};
    if (form_type_id !== undefined) updateData.form_type_id = form_type_id;
    if (form_parent_id !== undefined) updateData.form_parent_id = form_parent_id;
    if (title !== undefined) updateData.title = title;
    if (description !== undefined) updateData.description = description;
    if (created_by !== undefined) updateData.created_by = created_by;
    if (created_date !== undefined) updateData.created_date = created_date;
    if (end_date !== undefined) updateData.end_date = end_date;

    const userId = updated_by ?? req.user?.userId ?? req.user?.user_id;

    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        
        const updatedByUserId = req.user?.userId ?? null;
        const normalizedLocationIds = normalizeLocationIds(location_ids);
        // const updated = await updateForm(id, updateData, question_ids, normalizedLocationIds, connection, updatedByUserId);
        

        const updated = await updateForm(id, updateData, question_ids, location_ids, connection, userId);

        if (!updated) {
            await connection.rollback();
            return res.status(404).json({ success: false, message: 'Form not found' });
        }
        const [formRows] = await connection.query('SELECT created_by FROM sat_form_details WHERE form_id = ?', [id]);
        const whoDidAction = updatedByUserId ?? formRows[0]?.created_by;
        if (whoDidAction != null) {
            await insertFormLog(id, whoDidAction, 'UPDATED', connection);
        }
        await connection.commit();
        res.status(200).json({ success: true, message: 'Form updated successfully' });
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
});

// Delete form
exports.deleteForm = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const deleted = await deleteForm(id);
    
    if (!deleted) {
        return res.status(404).json({ success: false, message: 'Form not found' });
    }
    
    res.status(200).json({ success: true, message: 'Form deleted successfully' });
});

