<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class AjusteInventario extends MY_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('almacen/AjusteInventario_model');
    }

    protected function validar_permiso_ajax($slug) {
        if (!tiene_permiso($slug)) {
            echo json_encode(array('status' => false, 'message' => 'No tienes permisos'));
            exit;
        }
    }

    // ---------------------------------------------------------------
    // LISTADO
    // ---------------------------------------------------------------
    public function index() {
        $this->validar_permiso('ajuste_inventario_ver');

        $data['titulo']      = 'Ajuste de Inventario';
        $data['ajustes']     = $this->AjusteInventario_model->listar();
        $data['es_autorizador'] = $this->AjusteInventario_model->es_autorizador_ajuste($this->session->userdata('id'));
        $this->layout('almacen/ajuste_inventario/index', $data);
    }

    // ---------------------------------------------------------------
    // NUEVO
    // ---------------------------------------------------------------
    public function create() {
        $this->validar_permiso('ajuste_inventario_crear');

        $data['titulo']    = 'Nuevo Ajuste de Inventario';
        $data['almacenes'] = $this->AjusteInventario_model->listar_almacenes();
        $data['motivos']   = $this->AjusteInventario_model->listar_motivos();
        $this->layout('almacen/ajuste_inventario/create', $data);
    }

    // ---------------------------------------------------------------
    // GUARDAR
    // ---------------------------------------------------------------
    public function store() {
        $this->validar_permiso('ajuste_inventario_crear');

        $this->form_validation->set_rules('almacen_id',       'Almacén', 'required');
        $this->form_validation->set_rules('motivo_ajuste_id', 'Motivo',  'required');
        $this->form_validation->set_rules('fecha',            'Fecha',   'required');

        if ($this->form_validation->run() == FALSE) {
            $this->create();
            return;
        }

        $almacen_id       = $this->input->post('almacen_id', TRUE);
        $motivo_ajuste_id = $this->input->post('motivo_ajuste_id', TRUE);
        $fecha            = $this->input->post('fecha', TRUE);
        $observaciones    = trim($this->input->post('observaciones', TRUE));
        $detalle          = $this->input->post('detalle');

        if (empty($detalle) || !is_array($detalle)) {
            $this->session->set_flashdata('error', 'Debes agregar al menos un producto al ajuste');
            redirect('almacen/ajuste_inventario/create');
        }

        $detalleInsert = array();

        foreach ($detalle as $item) {
            $producto_id   = isset($item['producto_id'])   ? (int)$item['producto_id']    : 0;
            $stock_fisico  = isset($item['stock_fisico'])  ? (float)$item['stock_fisico']  : 0;
            $stock_sistema = isset($item['stock_sistema']) ? (float)$item['stock_sistema'] : 0;
            $descripcion   = isset($item['detalle'])       ? trim($item['detalle'])         : '';
            $precio_prom   = isset($item['precio_promedio']) ? (float)$item['precio_promedio'] : 0;

            if ($producto_id <= 0) continue;

            $diferencia = round($stock_fisico - $stock_sistema, 2);

            $detalleInsert[] = array(
                'producto_id'    => $producto_id,
                'stock_sistema'  => $stock_sistema,
                'stock_fisico'   => $stock_fisico,
                'diferencia'     => $diferencia,
                'precio_promedio'=> $precio_prom,
                'detalle'        => $descripcion
            );
        }

        if (empty($detalleInsert)) {
            $this->session->set_flashdata('error', 'No hay detalle válido para registrar');
            redirect('almacen/ajuste_inventario/create');
        }

        $cabecera = array(
            'fecha'           => $fecha,
            'almacen_id'      => $almacen_id,
            'motivo_ajuste_id'=> $motivo_ajuste_id,
            'observaciones'   => $observaciones !== '' ? $observaciones : null,
            'estado_id'       => 1, // BORRADOR
            'created_by'      => $this->session->userdata('id')
        );

        $this->db->trans_begin();

        $aj_id = $this->AjusteInventario_model->insertar_cabecera($cabecera);

        if (!$aj_id) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar el ajuste');
            redirect('almacen/ajuste_inventario/create');
        }

        foreach ($detalleInsert as &$d) {
            $d['aj_id'] = $aj_id;
        }
        unset($d);

        $this->AjusteInventario_model->insertar_detalle_batch($detalleInsert);

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'Error al guardar el ajuste');
            redirect('almacen/ajuste_inventario/create');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Ajuste N° ' . $aj_id . ' registrado en BORRADOR. Pendiente de aprobación.');
        redirect('almacen/ajuste_inventario');
    }

    // ---------------------------------------------------------------
    // VER
    // ---------------------------------------------------------------
    public function ver($id) {
        $this->validar_permiso('ajuste_inventario_ver');

        $ajuste = $this->AjusteInventario_model->obtener_completo($id);
        if (!$ajuste) show_404();

        $data['titulo']        = 'Detalle Ajuste de Inventario N° ' . $id;
        $data['ajuste']        = $ajuste;
        $data['detalle']       = $this->AjusteInventario_model->obtener_detalle($id);
        $data['es_autorizador'] = $this->AjusteInventario_model->es_autorizador_ajuste($this->session->userdata('id'));
        $this->layout('almacen/ajuste_inventario/ver', $data);
    }

    // ---------------------------------------------------------------
    // APROBAR (solo autorizadores)
    // ---------------------------------------------------------------
    public function aprobar($id) {
        $this->validar_permiso('ajuste_inventario_aprobar');

        if (!$this->AjusteInventario_model->es_autorizador_ajuste($this->session->userdata('id'))) {
            $this->session->set_flashdata('error', 'No tienes autorización para aprobar ajustes');
            redirect('almacen/ajuste_inventario');
        }

        $ajuste = $this->AjusteInventario_model->obtener($id);
        if (!$ajuste) show_404();

        if ($ajuste->estado_id != 1) {
            $this->session->set_flashdata('error', 'Solo se puede aprobar un ajuste en estado BORRADOR');
            redirect('almacen/ajuste_inventario');
        }

        $detalle    = $this->AjusteInventario_model->obtener_detalle($id);
        $almacen_id = $ajuste->almacen_id;

        $this->db->trans_begin();

        $this->AjusteInventario_model->actualizar($id, array(
            'estado_id'  => 2, // APROBADO
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->session->userdata('id')
        ));

        // Aplicar ajuste al stock
        foreach ($detalle as $d) {
            if ((float)$d->diferencia != 0) {
                $this->AjusteInventario_model->aplicar_ajuste_stock(
                    $d->producto_id,
                    $almacen_id,
                    $d->diferencia
                );
            }
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo aprobar el ajuste');
            redirect('almacen/ajuste_inventario');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Ajuste N° ' . $id . ' aprobado y stock actualizado correctamente');
        redirect('almacen/ajuste_inventario/ver/' . $id);
    }

    // ---------------------------------------------------------------
    // ANULAR
    // ---------------------------------------------------------------
    public function anular($id) {
        $this->validar_permiso('ajuste_inventario_anular');

        $ajuste = $this->AjusteInventario_model->obtener($id);
        if (!$ajuste) show_404();

        if ($ajuste->estado_id == 0) {
            $this->session->set_flashdata('error', 'El ajuste ya está anulado');
            redirect('almacen/ajuste_inventario');
        }

        $detalle    = $this->AjusteInventario_model->obtener_detalle($id);
        $almacen_id = $ajuste->almacen_id;

        $this->db->trans_begin();

        $this->AjusteInventario_model->actualizar($id, array(
            'estado_id'  => 0, // ANULADO
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->session->userdata('id')
        ));

        // Revertir stock solo si estaba APROBADO
        if ($ajuste->estado_id == 2) {
            foreach ($detalle as $d) {
                if ((float)$d->diferencia != 0) {
                    $this->AjusteInventario_model->revertir_ajuste_stock(
                        $d->producto_id,
                        $almacen_id,
                        $d->diferencia
                    );
                }
            }
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo anular el ajuste');
            redirect('almacen/ajuste_inventario');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Ajuste N° ' . $id . ' anulado correctamente');
        redirect('almacen/ajuste_inventario');
    }

    // ---------------------------------------------------------------
    // AJAX - BUSCAR PRODUCTO
    // ---------------------------------------------------------------
    public function buscar_producto() {
        $this->validar_permiso_ajax('ajuste_inventario_crear');
        $term       = trim($this->input->get('term', TRUE));
        $almacen_id = $this->input->get('almacen_id', TRUE);
        if (strlen($term) < 2) { echo json_encode(array()); return; }

        $productos = $this->AjusteInventario_model->buscar_producto($term, $almacen_id);
        $resultado = array();
        foreach ($productos as $item) {
            $resultado[] = array(
                'id'               => $item->id,
                'label'            => $item->codigo . ' | ' . $item->nombre,
                'value'            => $item->nombre,
                'codigo'           => $item->codigo,
                'nombre'           => $item->nombre,
                'unidad_abreviado' => $item->unidad_abreviado,
                'stock_actual'     => $item->stock_actual,
                'precio_promedio'  => $item->precio_promedio
            );
        }
        echo json_encode($resultado);
    }
}
