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

class ParteIngreso extends MY_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('almacen/ParteIngreso_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;
        }
    }

    // ---------------------------------------------------------------
    // INGRESO POR PRODUCCIÓN (formulario simplificado)
    // ---------------------------------------------------------------
    public function create_produccion() {
        $this->validar_permiso('parte_ingreso_crear');

        $data['titulo']    = 'Ingreso por Producción';
        $data['almacenes'] = $this->ParteIngreso_model->listar_almacenes();
        $this->layout('almacen/parte_ingreso/create_produccion', $data);
    }

    public function store_produccion() {
        $this->validar_permiso('parte_ingreso_crear');

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

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

        $almacen_id    = $this->input->post('almacen_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');
            redirect('almacen/parte_ingreso/create_produccion');
        }

        $detalleInsert = array();

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

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

            $detalleInsert[] = array(
                'producto_id'     => $producto_id,
                'detalle'         => $descripcion,
                'cantidad'        => $cantidad,
                'precio_unitario' => 0.0000,
                'subtotal'        => 0.00
            );
        }

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

        $cabecera = array(
            'tipoingreso'    => 'P',
            'fecha'          => $fecha,
            'almacen_id'     => $almacen_id,
            'moneda_id'      => 1,
            'tipocambio'     => 0.00,
            'proveedor_id'   => null,
            'ordc_id'        => null,
            'req_id'         => null,
            'nroguiaremision'=> null,
            'nrocomprobante' => null,
            'observaciones'  => $observaciones !== '' ? $observaciones : null,
            'estado'         => 1,
            'created_by'     => $this->session->userdata('id')
        );

        $this->db->trans_begin();

        $pi_id = $this->ParteIngreso_model->insertar_cabecera($cabecera);

        if (!$pi_id) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar el ingreso');
            redirect('almacen/parte_ingreso/create_produccion');
        }

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

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

        // Actualizar stock (sin precio promedio ya que precio = 0)
        foreach ($detalleInsert as $d) {
            $producto = $this->db->where('id', $d['producto_id'])->get('vt_producto')->row();
            if ($producto && $producto->maneja_stock) {
                $this->ParteIngreso_model->actualizar_stock(
                    $d['producto_id'],
                    $almacen_id,
                    $d['cantidad'],
                    0
                );
            }
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'Ocurrió un error al guardar el ingreso');
            redirect('almacen/parte_ingreso/create_produccion');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Ingreso por producción N° ' . $pi_id . ' registrado correctamente');
        redirect('almacen/parte_ingreso');
    }

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

        $data['titulo']  = 'Partes de Ingreso';
        $data['partes']  = $this->ParteIngreso_model->listar();
        $this->layout('almacen/parte_ingreso/index', $data);
    }

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

        $data['titulo']          = 'Nuevo Parte de Ingreso';
        $data['almacenes']       = $this->ParteIngreso_model->listar_almacenes();
        $data['monedas']         = $this->ParteIngreso_model->listar_monedas();
        $data['oc_autorizadas']  = $this->ParteIngreso_model->listar_oc_autorizadas();
        $data['requerimientos']  = $this->ParteIngreso_model->listar_requerimientos_pendientes();

        $this->layout('almacen/parte_ingreso/create', $data);
    }

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

        $this->form_validation->set_rules('tipoingreso', 'Tipo de ingreso', 'required');
        $this->form_validation->set_rules('fecha',       'Fecha',           'required');
        $this->form_validation->set_rules('almacen_id',  'Almacén',         'required');
        $this->form_validation->set_rules('moneda_id',   'Moneda',          'required');

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

        $tipoingreso    = $this->input->post('tipoingreso', TRUE);
        $fecha          = $this->input->post('fecha', TRUE);
        $almacen_id     = $this->input->post('almacen_id', TRUE);
        $moneda_id      = $this->input->post('moneda_id', TRUE);
        $tipocambio     = $this->input->post('tipocambio', TRUE) ?: null;
        $proveedor_id   = $this->input->post('proveedor_id', TRUE) ?: null;
        $ordc_id        = $this->input->post('ordc_id', TRUE) ?: null;
        $req_id         = $this->input->post('req_id', TRUE) ?: null;
        $nroguia        = trim($this->input->post('nroguiaremision', TRUE));
        $nrocomp        = trim($this->input->post('nrocomprobante', 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 detalle');
            redirect('almacen/parte_ingreso/create');
        }

        $detalleInsert = array();

        foreach ($detalle as $item) {
            $producto_id     = isset($item['producto_id'])     ? (int)$item['producto_id']      : 0;
            $descripcion     = 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;

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

            $subtotal = round($cantidad * $precio_unitario, 2);

            $detalleInsert[] = array(
                'producto_id'     => $producto_id,
                'detalle'         => $descripcion,
                'cantidad'        => $cantidad,
                'precio_unitario' => round($precio_unitario, 4),
                'subtotal'        => $subtotal
            );
        }

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

        $cabecera = array(
            'tipoingreso'    => $tipoingreso,
            'fecha'          => $fecha,
            'almacen_id'     => $almacen_id,
            'moneda_id'      => $moneda_id,
            'tipocambio'     => $tipocambio,
            'proveedor_id'   => $proveedor_id,
            'ordc_id'        => $ordc_id,
            'req_id'         => $req_id,
            'nroguiaremision'=> $nroguia !== '' ? $nroguia : null,
            'nrocomprobante' => $nrocomp !== '' ? $nrocomp : null,
            'observaciones'  => $observaciones !== '' ? $observaciones : null,
            'estado'         => 1,
            'created_by'     => $this->session->userdata('id')
        );

        $this->db->trans_begin();

        $pi_id = $this->ParteIngreso_model->insertar_cabecera($cabecera);

        if (!$pi_id) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar el parte de ingreso');
            redirect('almacen/parte_ingreso/create');
        }

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

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

        // Actualizar stock y precio promedio por cada producto
        foreach ($detalleInsert as $d) {
            $producto = $this->db->where('id', $d['producto_id'])->get('vt_producto')->row();
            if ($producto && $producto->maneja_stock) {
                $this->ParteIngreso_model->actualizar_stock(
                    $d['producto_id'],
                    $almacen_id,
                    $d['cantidad'],
                    $d['precio_unitario']
                );
            }

            // Actualizar saldo en OC si aplica
            if ($ordc_id) {
                $this->ParteIngreso_model->actualizar_saldo_oc($ordc_id, $d['producto_id'], $d['cantidad']);
            }
        }

        // Actualizar saldo en requerimiento si aplica
        if ($req_id) {
            $this->load->model('almacen/OrdenCompra_model');
            // Reutilizamos la lógica de requerimiento del modelo de OC
            // pero necesitamos simular el detalle con req_id
            foreach ($detalleInsert as $d) {
                $req_det = $this->db
                    ->where('req_id', $req_id)
                    ->where('producto_id', $d['producto_id'])
                    ->where('saldo >', 0)
                    ->get('lg_requerimiento_detalle')
                    ->row();

                if (!$req_det) continue;

                $nuevo_saldo = max(0, (float)$req_det->saldo - $d['cantidad']);
                $this->db->where('id', $req_det->id)
                         ->update('lg_requerimiento_detalle', array(
                             'saldo'      => $nuevo_saldo,
                             'updated_at' => date('Y-m-d H:i:s'),
                             'updated_by' => $this->session->userdata('id')
                         ));
            }

            $this->OrdenCompra_model->actualizar_estado_requerimiento($req_id);
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'Ocurrió un error al guardar el parte de ingreso');
            redirect('almacen/parte_ingreso/create');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Parte de ingreso N° ' . $pi_id . ' registrado correctamente');
        redirect('almacen/parte_ingreso');
    }

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

        $parte = $this->ParteIngreso_model->obtener_completo($id);
        if (!$parte) show_404();

        $data['titulo']  = 'Detalle Parte de Ingreso N° ' . $id;
        $data['parte']   = $parte;
        $data['detalle'] = $this->ParteIngreso_model->obtener_detalle($id);

        $this->layout('almacen/parte_ingreso/ver', $data);
    }

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

        $parte = $this->ParteIngreso_model->obtener($id);
        if (!$parte) show_404();

        if ($parte->estado == 0) {
            $this->session->set_flashdata('error', 'El parte de ingreso ya se encuentra anulado');
            redirect('almacen/parte_ingreso');
        }

        $detalle = $this->ParteIngreso_model->obtener_detalle($id);

        $this->db->trans_begin();

        $this->ParteIngreso_model->anular($id, $this->session->userdata('id'));

        // Revertir stock
        foreach ($detalle as $d) {
            if ($d->maneja_stock) {
                $this->ParteIngreso_model->revertir_stock(
                    $d->producto_id,
                    $parte->almacen_id,
                    $d->cantidad
                );
            }
        }

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

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Parte de ingreso N° ' . $id . ' anulado correctamente');
        redirect('almacen/parte_ingreso');
    }

    // ---------------------------------------------------------------
    // AJAX - PROVEEDOR
    // ---------------------------------------------------------------
    public function buscar_proveedor() {
        $this->validar_permiso_ajax('parte_ingreso_crear');
        $term = trim($this->input->get('term', TRUE));
        if (strlen($term) < 2) { echo json_encode(array()); return; }

        $proveedores = $this->ParteIngreso_model->buscar_proveedor($term);
        $resultado   = array();
        foreach ($proveedores as $item) {
            $resultado[] = array(
                'id'            => $item->id,
                'label'         => $item->razon_social . ' | ' . $item->nro_documento,
                'value'         => $item->razon_social,
                'razon_social'  => $item->razon_social,
                'nro_documento' => $item->nro_documento
            );
        }
        echo json_encode($resultado);
    }

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

        $productos = $this->ParteIngreso_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,
                'unidad_abreviado' => $item->unidad_abreviado,
                'precio_compra'    => $item->precio_compra,
                'maneja_stock'     => $item->maneja_stock
            );
        }
        echo json_encode($resultado);
    }

    // ---------------------------------------------------------------
    // AJAX - DETALLE DE OC
    // ---------------------------------------------------------------
    public function detalle_oc($ordc_id) {
        $this->validar_permiso_ajax('parte_ingreso_crear');
        $detalle = $this->ParteIngreso_model->obtener_detalle_oc($ordc_id);
        echo json_encode($detalle);
    }

    // ---------------------------------------------------------------
    // AJAX - DETALLE DE REQUERIMIENTO
    // ---------------------------------------------------------------
    public function detalle_requerimiento($req_id) {
        $this->validar_permiso_ajax('parte_ingreso_crear');
        $detalle = $this->ParteIngreso_model->obtener_detalle_requerimiento($req_id);
        echo json_encode($detalle);
    }
}