<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Sale;
use App\Models\SaleItem;
use App\Models\SalePayment;
use App\Models\Inventory;
use App\Models\CashRegister;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;

class SaleController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $user = Auth::user();
        $query = Sale::with(['user', 'items.product', 'invoice', 'payments']);
        
        $isAdmin = $user->role && $user->role->slug === 'admin';
        
        if (!$isAdmin) {
            $query->where('user_id', $user->id);
        }
        
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }
        
        if ($request->has('payment_method')) {
            $query->where('payment_method', $request->payment_method);
        }
        
        if ($request->has('date_from')) {
            $query->where('sale_date', '>=', $request->date_from);
        }
        
        if ($request->has('date_to')) {
            $query->where('sale_date', '<=', $request->date_to);
        }
        
        if ($request->has('customer_name')) {
            $query->where('customer_name', 'like', "%{$request->customer_name}%");
        }
        
        $sales = $query->orderBy('created_at', 'desc')->get();
        
        return response()->json([
            'sales' => $sales,
            'is_admin' => $isAdmin
        ]);
    }

    public function store(Request $request): JsonResponse
    {
        $user = Auth::user();
        
        $cashRegister = CashRegister::where('user_id', $user->id)
            ->where('status', 'open')
            ->orderBy('opening_time', 'desc')
            ->first();

        if (!$cashRegister) {
            return response()->json([
                'error' => 'Debe abrir la caja antes de realizar una venta',
                'code' => 'CASH_REGISTER_CLOSED'
            ], 400);
        }

        $validated = $request->validate([
            'sale_date' => 'required|date',
            'customer_name' => 'nullable|string|max:255',
            'customer_document' => 'nullable|string|max:50',
            'customer_email' => 'nullable|email',
            'customer_phone' => 'nullable|string|max:50',
            'customer_address' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.quantity' => 'required|integer|min:1',
            'items.*.unit_price' => 'required|numeric|min:0',
            'tax' => 'numeric|min:0',
            'discount' => 'numeric|min:0',
            'payment_method' => 'in:cash,card,transfer,credit',
            'payments' => 'nullable|array|min:1',
            'payments.*.payment_method' => 'required|in:cash,card,transfer,credit',
            'payments.*.amount' => 'required|numeric|min:0.01',
            'notes' => 'nullable|string',
        ]);

        foreach ($validated['items'] as $item) {
            $product = \App\Models\Product::find($item['product_id']);
            if ($product->stock < $item['quantity']) {
                return response()->json([
                    'error' => "Insufficient stock for product: {$product->name}. Available: {$product->stock}"
                ], 400);
            }
        }

        $validated['user_id'] = Auth::id();
        $validated['sale_number'] = 'SAL-' . date('YmdHis');
        
        $subtotal = 0;
        foreach ($validated['items'] as &$item) {
            $item['subtotal'] = $item['quantity'] * $item['unit_price'];
            $subtotal += $item['subtotal'];
        }
        unset($item);
        
        $validated['subtotal'] = $subtotal;
        $validated['tax'] = $validated['tax'] ?? 0;
        $validated['discount'] = $validated['discount'] ?? 0;
        $validated['total'] = $subtotal + $validated['tax'] - $validated['discount'];
        $validated['status'] = 'pending';
        $validated['cash_register_id'] = $cashRegister->id;

        // If payments provided, validate total matches
        if (isset($validated['payments'])) {
            $paymentsTotal = array_sum(array_column($validated['payments'], 'amount'));
            if (abs($paymentsTotal - $validated['total']) > 0.01) {
                return response()->json([
                    'error' => 'La suma de los pagos debe ser igual al total de la venta',
                ], 400);
            }
            // Set main payment method from first payment
            $validated['payment_method'] = $validated['payments'][0]['payment_method'];
        }

        $sale = Sale::create($validated);

        foreach ($validated['items'] as $item) {
            SaleItem::create([
                'sale_id' => $sale->id,
                'product_id' => $item['product_id'],
                'quantity' => $item['quantity'],
                'unit_price' => $item['unit_price'],
                'subtotal' => $item['subtotal'],
            ]);
        }

        // Save payments if provided
        if (isset($validated['payments'])) {
            foreach ($validated['payments'] as $payment) {
                SalePayment::create([
                    'sale_id' => $sale->id,
                    'payment_method' => $payment['payment_method'],
                    'amount' => $payment['amount'],
                ]);
            }
        }

        return response()->json($sale->load(['user', 'items.product', 'payments']), 201);
    }

    public function show(string $id): JsonResponse
    {
        $sale = Sale::with(['user', 'items.product', 'invoice'])->findOrFail($id);
        return response()->json($sale);
    }

    public function update(Request $request, string $id): JsonResponse
    {
        $sale = Sale::findOrFail($id);
        
        if (in_array($sale->status, ['completed', 'voided'])) {
            return response()->json(['error' => 'Cannot update a completed or voided sale'], 400);
        }

        $validated = $request->validate([
            'status' => 'sometimes|in:pending,completed,cancelled,voided',
            'payment_method' => 'sometimes|in:cash,card,transfer,credit',
            'notes' => 'nullable|string',
        ]);
        
        $sale->update($validated);
        
        return response()->json($sale->load(['user', 'items.product']));
    }

    public function destroy(string $id): JsonResponse
    {
        $sale = Sale::findOrFail($id);
        
        if (in_array($sale->status, ['completed', 'voided'])) {
            return response()->json(['error' => 'Cannot delete a completed or voided sale'], 400);
        }

        foreach ($sale->items as $item) {
            $product = $item->product;
            $product->update(['stock' => $product->stock + $item->quantity]);
            $item->delete();
        }
        
        $sale->delete();
        
        return response()->json(['message' => 'Sale deleted successfully']);
    }

    public function complete(string $id): JsonResponse
    {
        $sale = Sale::findOrFail($id);
        
        if ($sale->status !== 'pending') {
            return response()->json(['error' => 'Only pending sales can be completed'], 400);
        }

        foreach ($sale->items as $item) {
            $product = $item->product;
            $previousStock = $product->stock;
            $newStock = $previousStock - $item['quantity'];
            
            $product->update(['stock' => $newStock]);

            Inventory::create([
                'product_id' => $product->id,
                'user_id' => Auth::id(),
                'type' => 'out',
                'quantity' => $item['quantity'],
                'previous_stock' => $previousStock,
                'new_stock' => $newStock,
                'reference_type' => 'sale',
                'reference_id' => $sale->id,
                'notes' => 'Sale completed: ' . $sale->sale_number,
            ]);
        }

        $sale->update(['status' => 'completed']);
        
        return response()->json($sale->load(['user', 'items.product']));
    }

    public function cancel(string $id): JsonResponse
    {
        $sale = Sale::findOrFail($id);
        
        if ($sale->status !== 'pending') {
            return response()->json(['error' => 'Only pending sales can be cancelled'], 400);
        }

        $sale->update(['status' => 'cancelled']);
        
        return response()->json($sale->load(['user', 'items.product']));
    }
}
