<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
use yii\web\UploadedFile;
use yii\helpers\ArrayHelper;
use app\models\ProcesoForm;
use app\models\Pedidos;
use app\models\Clientes;
use app\models\Producto;
use app\models\Cotizacion;
use app\models\CotizacionItem;
use app\models\CotizacionItems;
use app\models\PedidoReportePrecios;

// Usamos la librería OpenSpout que ya tienes
use OpenSpout\Reader\XLSX\Reader;

class ProcesoController extends Controller
{
    /**
     * Inicia el proceso de carga de archivo.
     * Muestra un formulario para seleccionar cliente y archivo Excel.
     * Procesa el archivo y genera el reporte de precios.
     */
    public function actionIniciar()
    {
        $formModel = new ProcesoForm();
        $listaClientes = ArrayHelper::map(Clientes::find()->orderBy(['nombre_razon_social' => SORT_ASC])->all(), 'id', 'nombre_razon_social');

        if (Yii::$app->request->isPost) {
            $formModel->load(Yii::$app->request->post());
            $formModel->archivoExcel = UploadedFile::getInstance($formModel, 'archivoExcel');

            if ($formModel->validate()) {
                
                // Asegurarse de que la carpeta 'uploads' exista y tenga permisos
                $rutaDirectorio = Yii::getAlias('@webroot/uploads');
                if (!is_dir($rutaDirectorio)) {
                    mkdir($rutaDirectorio, 0777, true);
                }
                
                $rutaArchivo = $rutaDirectorio . '/' . uniqid() . '.' . $formModel->archivoExcel->extension;

                $transaction = Yii::$app->db->beginTransaction();
                try {
                    // Guardar el archivo subido
                    if (!$formModel->archivoExcel->saveAs($rutaArchivo)) {
                        throw new \Exception('Error al guardar el archivo subido.');
                    }
                
                    // Paso A: Crear el registro 'pedidos' padre
                    $pedido = new Pedidos();
                    $pedido->cliente_id = $formModel->cliente_id;
                    $pedido->estado = 'reporte_generado';
                    if (!$pedido->save()) {
                        throw new \Exception('No se pudo crear el registro del pedido.');
                    }

                    // Paso B: Leer el Excel con OpenSpout
                    $reader = new Reader();
                    $reader->open($rutaArchivo);

                    $filasProcesadas = 0;

                    foreach ($reader->getSheetIterator() as $sheet) {
                        foreach ($sheet->getRowIterator() as $row) {
                            // Omitir la primera fila (cabecera)
                            if ($filasProcesadas === 0) {
                                $filasProcesadas++;
                                continue;
                            }

                            $cells = $row->getCells();
                            $codigoProducto = trim($cells[0]->getValue()); // Columna A (índice 0)
                            $cantidad = (int)trim($cells[1]->getValue()); // Columna B (índice 1)

                            if (empty($codigoProducto)) continue;
                            
                            // Paso C: Buscar producto
                            $producto = Producto::findOne(['codigo_producto' => $codigoProducto]);
                            if ($producto === null) {
                                // Aquí puedes decidir si saltar o crear un producto nuevo
                                // Por ahora, lanzamos un error para ser estrictos.
                                throw new \Exception("El producto con código '$codigoProducto' no fue encontrado en la base de datos.");
                            }

                            // Paso D: Buscar los 3 últimos precios
                            $ultimosPrecios = CotizacionItems::find()
                                ->joinWith('cotizacion') // Unimos con la tabla 'cotizaciones' para poder ordenar por fecha
                                ->where(['producto_id' => $producto->id])
                                ->orderBy(['cotizaciones.fecha_cotizacion' => SORT_DESC])
                                ->limit(3)
                                ->all();
                            
                            // Paso E: Guardar en el reporte
                            $reporte = new PedidoReportePrecios();
                            $reporte->pedido_id = $pedido->id;
                            $reporte->producto_id = $producto->id;

                            // Llenar los precios encontrados
                            if (isset($ultimosPrecios[0])) {
                                $reporte->precio_1 = $ultimosPrecios[0]->precio_unitario_fob;
                                $reporte->orden_1 = $ultimosPrecios[0]->cotizacion->numero_orden;
                                $reporte->fecha_1 = $ultimosPrecios[0]->cotizacion->fecha_cotizacion;
                            }
                            if (isset($ultimosPrecios[1])) {
                                $reporte->precio_2 = $ultimosPrecios[1]->precio_unitario_fob;
                                $reporte->orden_2 = $ultimosPrecios[1]->cotizacion->numero_orden;
                                $reporte->fecha_2 = $ultimosPrecios[1]->cotizacion->fecha_cotizacion;
                            }
                            if (isset($ultimosPrecios[2])) {
                                $reporte->precio_3 = $ultimosPrecios[2]->precio_unitario_fob;
                                $reporte->orden_3 = $ultimosPrecios[2]->cotizacion->numero_orden;
                                $reporte->fecha_3 = $ultimosPrecios[2]->cotizacion->fecha_cotizacion;
                            }

                            if (!$reporte->save()) {
                                throw new \Exception('No se pudo guardar el reporte de precios para el producto ' . $codigoProducto);
                            }
                            
                            $filasProcesadas++;
                        }
                    }
                    
                    $reader->close();
                    
                    $transaction->commit();
                    Yii::$app->session->setFlash('success', 'Archivo procesado. Reporte de precios generado exitosamente.');
                    
                    // Paso F: Redirigir al reporte
                    return $this->redirect(['ver-reporte', 'id' => $pedido->id]);

                } catch (\Exception $e) {
                    $transaction->rollBack();
                    Yii::$app->session->setFlash('error', 'Error al procesar: ' . $e->getMessage());
                }
            }
        }

        return $this->render('iniciar', [
            'model' => $formModel,
            'listaClientes' => $listaClientes,
        ]);
    }

    /**
     * Muestra el reporte de precios generado para un pedido.
     * @param integer $id
     * @return string
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionVerReporte($id)
    {
        // Esta es la página final del Paso 3
        // Aquí deberás hacer una consulta a la tabla 'pedido_reporte_precios'
        // usando el $id del pedido para mostrar los resultados.
        
        $pedido = Pedidos::findOne($id);
        if ($pedido === null) {
            throw new \yii\web\NotFoundHttpException('El pedido no existe.');
        }

        return $this->render('ver-reporte', [
            'pedido' => $pedido
        ]);
    }
}