'use strict'

const { Op } = require('sequelize');
const Cargo = require('../models/cargo');

function toUpper(str) {
    return str ? str.toString().trim().toUpperCase() : '';
}

async function listarCargos(req, res) {
    try {
        const cargos = await Cargo.findAll({ order: [['ID_CARGO', 'ASC']] });
        res.status(200).json({ message: 'Cargos obtenidos', data: cargos });
    } catch (err) {
        res.status(500).json({ message: 'Error al obtener cargos', error: err.message });
    }
}

async function obtenerCargo(req, res) {
    try {
        const cargo = await Cargo.findByPk(req.params.id);
        if (!cargo) return res.status(404).json({ message: 'Cargo no encontrado' });
        res.status(200).json({ message: 'Cargo obtenido', data: cargo });
    } catch (err) {
        res.status(500).json({ message: 'Error al obtener cargo', error: err.message });
    }
}

async function registrarCargo(req, res) {
    try {
        const descripcion = toUpper(req.body.DESCRIPCION);
        if (!descripcion) return res.status(400).json({ message: 'La descripción es obligatoria' });

        const existe = await Cargo.findOne({ where: { DESCRIPCION: descripcion } });
        if (existe) return res.status(409).json({ message: 'Ya existe un cargo con esa descripción' });

        const nuevo = await Cargo.create({
            ID_AREA: req.body.ID_AREA,
            CODIGO: 0,
            DESCRIPCION: descripcion,
            ESTADO: 1
        });
        res.status(201).json({ message: 'Cargo registrado exitosamente', data: nuevo });
    } catch (err) {
        res.status(500).json({ message: 'Error al registrar cargo', error: err.message });
    }
}

async function actualizarCargo(req, res) {
    try {
        const cargo = await Cargo.findByPk(req.params.id);
        if (!cargo) return res.status(404).json({ message: 'Cargo no encontrado' });

        const descripcion = toUpper(req.body.DESCRIPCION);
        if (!descripcion) return res.status(400).json({ message: 'La descripción es obligatoria' });

        const duplicado = await Cargo.findOne({
            where: { DESCRIPCION: descripcion, ID_CARGO: { [Op.ne]: req.params.id } }
        });
        if (duplicado) return res.status(409).json({ message: 'Ya existe otro cargo con esa descripción' });

        await Cargo.update(
            { ID_AREA: req.body.ID_AREA, DESCRIPCION: descripcion },
            { where: { ID_CARGO: req.params.id } }
        );
        res.status(200).json({ message: 'Cargo actualizado exitosamente' });
    } catch (err) {
        res.status(500).json({ message: 'Error al actualizar cargo', error: err.message });
    }
}

async function cambiarEstadoCargo(req, res) {
    try {
        const cargo = await Cargo.findByPk(req.params.id);
        if (!cargo) return res.status(404).json({ message: 'Cargo no encontrado' });

        const nuevoEstado = cargo.ESTADO === 1 ? 0 : 1;
        await Cargo.update({ ESTADO: nuevoEstado }, { where: { ID_CARGO: req.params.id } });

        res.status(200).json({
            message: `Cargo ${nuevoEstado === 1 ? 'activado' : 'desactivado'} exitosamente`,
            estado: nuevoEstado
        });
    } catch (err) {
        res.status(500).json({ message: 'Error al cambiar estado del cargo', error: err.message });
    }
}

module.exports = { listarCargos, obtenerCargo, registrarCargo, actualizarCargo, cambiarEstadoCargo };
