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

class Requerimientos extends MY_Controller {

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

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

    public function index() {
        $this->validar_permiso('requerimientos_ver');

        $data['titulo'] = 'Requerimientos';
        $data['requerimientos'] = $this->Requerimiento_model->listar();

        $this->layout('logistica/requerimientos/index', $data);
    }

    public function create($orp_id = 0) {
        $this->validar_permiso('requerimientos_crear');

        $estadoInicial = $this->Requerimiento_model->obtener_estado_por_tipo_codigo('REQUERIMIENTO', 'PAT');

        $data['titulo'] = 'Nuevo Requerimiento';
        $data['estado_inicial'] = $estadoInicial;
        $data['categorias'] = $this->Requerimiento_model->obtener_categorias_producto();
        $data['monedas'] = $this->Requerimiento_model->obtener_monedas();
        $data['unidades'] = $this->Requerimiento_model->obtener_unidades();
        $data['orp_id'] = (int)$orp_id;

        $this->layout('logistica/requerimientos/create', $data);
    }


    public function buscar_producto() {
        $this->validar_permiso_ajax('requerimientos_crear');

        $term = trim($this->input->get('term', TRUE));

        if (strlen($term) < 2) {
            echo json_encode(array());
            return;
        }

        $productos = $this->Requerimiento_model->buscar_producto($term);
        $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,
                'descripcion' => $item->descripcion,
                'precio_unidad' => (float)$item->precio_unidad,
                'unidad_abreviado' => $item->unidad_abreviado
            );
        }

        echo json_encode($resultado);
    }

    public function obtener_producto_ajax($id) {
        $this->validar_permiso_ajax('requerimientos_crear');

        $producto = $this->Requerimiento_model->obtener_producto($id);

        if (!$producto) {
            echo json_encode(array(
                'status' => false,
                'message' => 'Producto no encontrado'
            ));
            return;
        }

        echo json_encode(array(
            'status' => true,
            'data' => array(
                'id' => $producto->id,
                'codigo' => $producto->codigo,
                'nombre' => $producto->nombre,
                'descripcion' => $producto->descripcion,
                'precio_unidad' => (float)$producto->precio_unidad,
                'unidad_abreviado' => $producto->unidad_abreviado
            )
        ));
    }

    public function guardar_producto_rapido() {
        $this->validar_permiso_ajax('requerimientos_crear');

        $categoria_id = $this->input->post('categoria_id', TRUE);
        $codigo = strtoupper(trim($this->input->post('codigo', TRUE)));
        $nombre = strtoupper(trim($this->input->post('nombre', TRUE)));
        $descripcion = trim($this->input->post('descripcion', TRUE));
        $moneda_id_compra = $this->input->post('moneda_id_compra', TRUE);
        $precio_compra = $this->input->post('precio_compra', TRUE);
        $um_id_compra = $this->input->post('um_id_compra', TRUE);
        $precio_unidad = $this->input->post('precio_unidad', TRUE);

        if (empty($categoria_id) || $codigo === '' || $nombre === '' || empty($moneda_id_compra) || empty($um_id_compra)) {
            echo json_encode(array(
                'status' => false,
                'message' => 'Completa los campos obligatorios del producto'
            ));
            return;
        }

        $almacen = $this->Requerimiento_model->obtener_almacen_principal();

        if (!$almacen) {
            echo json_encode(array(
                'status' => false,
                'message' => 'No existe un almacén activo para registrar el producto'
            ));
            return;
        }

        $this->db->trans_begin();

        $producto_id = $this->Requerimiento_model->insertar_producto_rapido(array(
            'categoria_id' => $categoria_id,
            'codigo' => $codigo,
            'nombre' => $nombre,
            'descripcion' => $descripcion !== '' ? $descripcion : null,
            'moneda_id_compra' => $moneda_id_compra,
            'precio_compra' => $precio_compra !== '' ? $precio_compra : 0,
            'um_id_compra' => $um_id_compra,
            'moneda_id_venta' => 1,
            'precio_unidad' => $precio_unidad !== '' ? $precio_unidad : 0,
            'precio_doce' => 0,
            'precio_veinticinco' => 0,
            'precio_cincuenta' => 0,
            'precio_cien' => 0,
            'precio_millar' => 0,
            'um_id_venta' => 1,
            'bien_serv' => 'B',
            'maneja_stock' => 1,
            'activo_compra' => 1,
            'activo_venta' => 1,
            'tafigv_id' => 1,
            'detraccion_id' => 1,
            'estado' => 1,
            'created_by' => $this->session->userdata('id')
        ));

        if (!$producto_id) {
            $this->db->trans_rollback();
            echo json_encode(array(
                'status' => false,
                'message' => 'No se pudo crear el producto'
            ));
            return;
        }

        $this->Requerimiento_model->insertar_producto_almacen(array(
            'producto_id' => $producto_id,
            'almacen_id' => $almacen->id,
            'cantidad_stock' => 0.00,
            'cantidad_reposicion' => 0.00,
            'cantidad_comprometida' => 0.00,
            'cantidad_minima' => 0.00,
            'cantidad_maxima' => 0.00,
            'precio_promedio' => 0.0000,
            'created_by' => $this->session->userdata('id')
        ));

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            echo json_encode(array(
                'status' => false,
                'message' => 'No se pudo registrar el producto'
            ));
            return;
        }

        $this->db->trans_commit();

        $producto = $this->Requerimiento_model->obtener_producto($producto_id);

        echo json_encode(array(
            'status' => true,
            'message' => 'Producto creado correctamente',
            'data' => array(
                'id' => $producto->id,
                'codigo' => $producto->codigo,
                'nombre' => $producto->nombre,
                'descripcion' => $producto->descripcion,
                'precio_unidad' => (float)$producto->precio_unidad,
                'unidad_abreviado' => $producto->unidad_abreviado
            )
        ));
    }

    public function store() {
        $this->validar_permiso('requerimientos_crear');

        $this->form_validation->set_rules('tipo', 'Tipo', 'required');
        $this->form_validation->set_rules('fecha', 'Fecha', 'required');
        $this->form_validation->set_rules('estado_id', 'Estado', 'required');

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

        $detalle = $this->input->post('detalle');

        if (empty($detalle) || !is_array($detalle)) {
            $this->session->set_flashdata('error', 'Debes agregar al menos un producto al detalle');
            $orp_id_post = (int)$this->input->post('orp_id', TRUE);

            if ($orp_id_post > 0) {
                redirect('ventas/orden-pedido/requerimientos/' . $orp_id_post);
            } else {
                redirect('logistica/requerimientos');
            }
        }

        $cabecera = array(
            'tipo'          => $this->input->post('tipo', TRUE),
            'fecha'         => $this->input->post('fecha', TRUE),
            'empleado_id'   => $this->session->userdata('id'),
            'observaciones' => trim($this->input->post('observaciones', TRUE)) ?: null,
            'orp_id'        => (int)$this->input->post('orp_id', TRUE),
            'estado_id'     => $this->input->post('estado_id', TRUE),
            'created_by'    => $this->session->userdata('id')
        );

        $detalleInsert = array();

        foreach ($detalle as $item) {
            $producto_id = isset($item['producto_id']) ? (int)$item['producto_id'] : 0;
            $detalleTexto = isset($item['detalle']) ? trim($item['detalle']) : '';
            $cantidad = isset($item['cantidad']) ? (float)$item['cantidad'] : 0;
            $precio_unitario = isset($item['precio_unitario']) ? (float)$item['precio_unitario'] : 0;
            $total = round($cantidad * $precio_unitario, 2);

            if ($producto_id <= 0 || $cantidad <= 0) {
                continue;
            }

            $detalleInsert[] = array(
                'producto_id' => $producto_id,
                'detalle' => $detalleTexto !== '' ? $detalleTexto : null,
                'cantidad' => $cantidad,
                'saldo' => $cantidad,
                'precio_unitario' => round($precio_unitario, 4),
                'total' => $total,
                'estado_id' => $this->input->post('estado_id', TRUE),
                'created_by' => $this->session->userdata('id')
            );
        }

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

        $this->db->trans_begin();

        $req_id = $this->Requerimiento_model->insertar($cabecera);

        if (!$req_id) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar el requerimiento');
            $orp_id_post = (int)$this->input->post('orp_id', TRUE);
            if ($orp_id_post > 0) {
                redirect('logistica/requerimientos/create/' . $orp_id_post);
            } else {
                redirect('logistica/requerimientos/create');
            }

        }

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

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

        $this->Requerimiento_model->insertar_estado(array(
            'req_id' => $req_id,
            'estado_id' => $this->input->post('estado_id', TRUE),
            'req_fechaestado' => date('Y-m-d H:i:s'),
            'usuario_id' => $this->session->userdata('id')
        ));

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo guardar el requerimiento');
            redirect('logistica/requerimientos/create');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Requerimiento registrado correctamente');
        redirect('logistica/requerimientos');
    }

    public function ver($id) {
        $this->validar_permiso('requerimientos_ver');

        $requerimiento = $this->Requerimiento_model->obtener_completo($id);

        if (!$requerimiento) {
            show_404();
        }

        $detalle = $this->Requerimiento_model->obtener_detalle($id);
        $historial = $this->Requerimiento_model->obtener_historial_estados($id);

        $data['titulo'] = 'Detalle de Requerimiento';
        $data['requerimiento'] = $requerimiento;
        $data['detalle'] = $detalle;
        $data['historial'] = $historial;

        $this->layout('logistica/requerimientos/ver', $data);
    }

    public function edit($id) {
        $this->validar_permiso('requerimientos_editar');

        $requerimiento = $this->Requerimiento_model->obtener($id);

        if (!$requerimiento) {
            show_404();
        }

        $estadoActual = $this->db
            ->where('id', $requerimiento->estado_id)
            ->get('estado')
            ->row();

        if ($estadoActual && in_array($estadoActual->codigo, array('ANU', 'CER', 'ATE'))) {
            $this->session->set_flashdata('error', 'El requerimiento no se puede editar por su estado actual');
            redirect('logistica/requerimientos');
        }

        $data['titulo'] = 'Editar Requerimiento';
        $data['requerimiento'] = $this->Requerimiento_model->obtener_completo($id);
        $data['detalle'] = $this->Requerimiento_model->obtener_detalle($id);
        $data['categorias'] = $this->Requerimiento_model->obtener_categorias_producto();
        $data['monedas'] = $this->Requerimiento_model->obtener_monedas();
        $data['unidades'] = $this->Requerimiento_model->obtener_unidades();
        $data['orp_id'] = (int)$requerimiento->orp_id;

        $this->layout('logistica/requerimientos/edit', $data);
    }

    public function update($id) {
        $this->validar_permiso('requerimientos_editar');

        $requerimiento = $this->Requerimiento_model->obtener($id);

        if (!$requerimiento) {
            show_404();
        }

        $estadoActual = $this->db
            ->where('id', $requerimiento->estado_id)
            ->get('estado')
            ->row();

        if ($estadoActual && in_array($estadoActual->codigo, array('ANU', 'CER', 'ATE'))) {
            $this->session->set_flashdata('error', 'El requerimiento no se puede editar por su estado actual');
            redirect('logistica/requerimientos');
        }

        $this->form_validation->set_rules('tipo', 'Tipo', 'required');
        $this->form_validation->set_rules('fecha', 'Fecha', 'required');

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

        $detalle = $this->input->post('detalle');

        if (empty($detalle) || !is_array($detalle)) {
            $this->session->set_flashdata('error', 'Debes agregar al menos un producto al detalle');
            redirect('logistica/requerimientos/edit/'.$id);
        }

        $cabecera = array(
            'tipo' => $this->input->post('tipo', TRUE),
            'fecha' => $this->input->post('fecha', TRUE),
            'observaciones' => trim($this->input->post('observaciones', TRUE)) ?: null,
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->session->userdata('id')
        );

        $detalleInsert = array();

        foreach ($detalle as $item) {
            $producto_id = isset($item['producto_id']) ? (int)$item['producto_id'] : 0;
            $detalleTexto = isset($item['detalle']) ? trim($item['detalle']) : '';
            $cantidad = isset($item['cantidad']) ? (float)$item['cantidad'] : 0;
            $precio_unitario = isset($item['precio_unitario']) ? (float)$item['precio_unitario'] : 0;
            $total = round($cantidad * $precio_unitario, 2);

            if ($producto_id <= 0 || $cantidad <= 0) {
                continue;
            }

            $detalleInsert[] = array(
                'req_id' => $id,
                'producto_id' => $producto_id,
                'detalle' => $detalleTexto !== '' ? $detalleTexto : null,
                'cantidad' => $cantidad,
                'saldo' => $cantidad,
                'precio_unitario' => round($precio_unitario, 4),
                'total' => $total,
                'estado_id' => $requerimiento->estado_id,
                'created_by' => $this->session->userdata('id')
            );
        }

        if (empty($detalleInsert)) {
            $this->session->set_flashdata('error', 'No existe detalle válido para actualizar');
            redirect('logistica/requerimientos/edit/'.$id);
        }

        $this->db->trans_begin();

        $this->Requerimiento_model->actualizar($id, $cabecera);
        $this->Requerimiento_model->eliminar_detalle($id);
        $this->Requerimiento_model->insertar_detalle_batch($detalleInsert);

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo actualizar el requerimiento');
            redirect('logistica/requerimientos/edit/'.$id);
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Requerimiento actualizado correctamente');

        if ((int)$requerimiento->orp_id > 0) {
            redirect('ventas/orden-pedido/requerimientos/'.$requerimiento->orp_id);
        } else {
            redirect('logistica/requerimientos');
        }
    }

    public function estado($id) {
        $this->validar_permiso('requerimientos_eliminar');

        $requerimiento = $this->Requerimiento_model->obtener($id);

        if (!$requerimiento) {
            show_404();
        }

        $estadoActual = $this->db
            ->where('id', $requerimiento->estado_id)
            ->get('estado')
            ->row();

        if (!$estadoActual) {
            $this->session->set_flashdata('error', 'No se encontró el estado actual del requerimiento');
            redirect('logistica/requerimientos');
        }

        if ($estadoActual->codigo == 'ANU') {
            $this->session->set_flashdata('error', 'El requerimiento ya se encuentra anulado');
            redirect('logistica/requerimientos');
        }

        $estadoAnulado = $this->Requerimiento_model->obtener_estado_por_tipo_codigo('REQUERIMIENTO', 'ANU');

        if (!$estadoAnulado) {
            $this->session->set_flashdata('error', 'No se encontró el estado ANULADO para requerimiento');
            redirect('logistica/requerimientos');
        }

        $this->db->trans_begin();

        $this->Requerimiento_model->cambiarEstado(
            $id,
            $estadoAnulado->id,
            $this->session->userdata('id')
        );

        $this->Requerimiento_model->insertar_estado(array(
            'req_id' => $id,
            'estado_id' => $estadoAnulado->id,
            'req_fechaestado' => date('Y-m-d H:i:s'),
            'usuario_id' => $this->session->userdata('id')
        ));

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

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Requerimiento anulado correctamente');
        redirect('logistica/requerimientos');
    }
}