<?php
// app/Services/InventoryService.php

namespace App\Services;

use App\Models\Product;
use App\Models\InventoryMovement;
use App\Models\ProductStockSnapshot;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class InventoryService
{
    // Obtener stock histórico de un producto
    public function getStockAtDate($productId, $date, ?int $companyId = null)
    {
        $query = InventoryMovement::where('product_id', $productId)
            ->whereDate('created_at', '<=', $date);

        if ($companyId !== null && $companyId > 0) {
            $query->where('company_id', $companyId);
        }

        return $query->sum('quantity');
    }
    
    // Generar snapshot de stock para todos los productos
    public function generateDailySnapshot()
    {
        $today = Carbon::today();
        
        $products = Product::all();
        
        foreach ($products as $product) {
            ProductStockSnapshot::updateOrCreate(
                [
                    'product_id' => $product->id,
                    'snapshot_date' => $today
                ],
                [
                    'current_stock' => $product->current_stock,
                    'notes' => 'Snapshot diario automático'
                ]
            );
        }
        
        return true;
    }
    
    // Recalcular stock de un producto desde cero basado en movimientos
    public function recalculateStock($productId, ?int $companyId = null)
    {
        $product = Product::findOrFail($productId);

        $query = InventoryMovement::where('product_id', $productId);
        if ($companyId !== null && $companyId > 0) {
            $query->where('company_id', $companyId);
        }
        $calculatedStock = $query->sum('quantity');

        DB::transaction(function () use ($product, $calculatedStock, $companyId) {
            $oldStock = $product->current_stock;
            $product->current_stock = $calculatedStock;
            $product->save();

            if ($oldStock != $calculatedStock) {
                InventoryMovement::create([
                    'product_id' => $product->id,
                    'movement_type' => 'adjustment',
                    'reference_type' => 'recalculation',
                    'reference_id' => 0,
                    'quantity' => $calculatedStock - $oldStock,
                    'stock_before' => $oldStock,
                    'stock_after' => $calculatedStock,
                    'unit_cost' => $product->purchase_price,
                    'total_cost' => $product->purchase_price * abs($calculatedStock - $oldStock),
                    'notes' => 'Recalculación automática de stock',
                    'created_by' => auth()->id(),
                    'company_id' => $companyId,
                ]);
            }
        });

        return $calculatedStock;
    }

    public function getProductMovementReport($productId, $startDate = null, $endDate = null, ?int $companyId = null)
    {
        $query = InventoryMovement::with(['product', 'creator'])
            ->where('product_id', $productId)
            ->orderBy('created_at', 'desc');

        if ($companyId !== null && $companyId > 0) {
            $query->where('company_id', $companyId);
        }

        if ($startDate) {
            $query->whereDate('created_at', '>=', $startDate);
        }
        if ($endDate) {
            $query->whereDate('created_at', '<=', $endDate);
        }

        return $query->get();
    }

    public function calculateCOGS($productId = null, $startDate, $endDate, ?int $companyId = null)
    {
        $query = InventoryMovement::where('movement_type', 'sale')
            ->whereBetween('created_at', [$startDate, $endDate]);

        if ($companyId !== null && $companyId > 0) {
            $query->where('company_id', $companyId);
        }

        if ($productId) {
            $query->where('product_id', $productId);
        }

        return $query->sum(DB::raw('ABS(quantity) * unit_cost'));
    }
}