<?php

namespace App\Http\Controllers;

use App\Exports\ProduitsExport;
use App\Models\Fournisseur;
use App\Models\Magasin;
use App\Models\Mouvement;
use App\Models\Produit;
use App\Models\Stock;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Facades\Excel;

/**
 * Contrôleur des produits.
 * Gère les opérations CRUD avec fournisseur et stock initial.
 */
class ProduitController extends Controller
{
    public function create()
    {
        return redirect()->route('produits.index');
    }

    public function edit(string $id)
    {
        return redirect()->route('produits.index');
    }

    public function index(Request $request)
    {
        $query = Produit::with(['fournisseur', 'stock.magasin'])->latest();

        if ($request->filled('fournisseur_id')) {
            $query->where('fournisseur_id', $request->fournisseur_id);
        }

        if ($request->filled('produit_id')) {
            $query->where('id', $request->produit_id);
        }

        $produits = $query->paginate(10)->withQueryString();

        $fournisseurs = Fournisseur::whereNull('deleted_at')->orderBy('nom')->get();
        $magasins = Magasin::where('disabled', false)->orderBy('nom')->get();
        $produitsFiltre = Produit::orderBy('designation')->get(['id', 'designation', 'reference']);

        return view('produits.index', compact('produits', 'fournisseurs', 'magasins', 'produitsFiltre'));
    }

    public function export(Request $request)
    {
        $query = Produit::with(['fournisseur', 'stock.magasin'])->latest();

        if ($request->filled('fournisseur_id')) {
            $query->where('fournisseur_id', $request->fournisseur_id);
        }

        if ($request->filled('produit_id')) {
            $query->where('id', $request->produit_id);
        }

        $produits = $query->get();

        $filename = 'produits';
        if ($request->filled('fournisseur_id')) {
            $fournisseur = Fournisseur::find($request->fournisseur_id);
            $filename .= '_' . ($fournisseur ? Str::slug($fournisseur->nom) : $request->fournisseur_id);
        }
        if ($request->filled('produit_id')) {
            $produit = Produit::find($request->produit_id);
            $filename .= '_' . ($produit ? Str::slug($produit->designation) : $request->produit_id);
        }
        $filename .= '_' . now()->format('Y-m-d_H-i') . '.xlsx';

        return Excel::download(new ProduitsExport($produits), $filename);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'designation' => 'required|string|max:255',
            'fournisseur_id' => 'nullable|exists:fournisseurs,id',
            'prix' => 'required|numeric|min:0',
            'prix_vente' => 'required|numeric|min:0',
            'unite' => 'nullable|string|max:20',
            'magasin_id' => 'required|exists:magasins,id',
            'quantite' => 'required|integer|min:0',
            'seuil_alerte' => 'required|integer|min:0',
        ]);

        $produit = Produit::create([
            'designation' => $validated['designation'],
            'fournisseur_id' => $validated['fournisseur_id'] ?? null,
            'prix' => $validated['prix'],
            'prix_vente' => $validated['prix_vente'],
            'unite' => $validated['unite'] ?: null,
        ]);

        Stock::create([
            'magasin_id' => $validated['magasin_id'],
            'produit_id' => $produit->id,
            'quantite' => $validated['quantite'],
            'seuil_alerte' => $validated['seuil_alerte'],
        ]);

        if($validated['quantite'] > 0)
        Mouvement::create([
            'type' => Mouvement::TYPE_STOCK_INITIAL,
            'magasin_id' => $validated['magasin_id'],
            'produit_id' => $produit->id,
            'quantite' => $validated['quantite'],
        ]);
        @endif

        return redirect()->route('produits.index')->with('success', 'Produit créé avec succès');
    }

    public function update(Request $request, string $id)
    {
        $validated = $request->validate([
            'designation' => 'required|string|max:255',
            'fournisseur_id' => 'nullable|exists:fournisseurs,id',
            'prix' => 'required|numeric|min:0',
            'prix_vente' => 'required|numeric|min:0',
            'unite' => 'nullable|string|max:20',
            'magasin_id' => 'nullable|exists:magasins,id',
            'quantite' => 'nullable|integer|min:0',
            'seuil_alerte' => 'nullable|integer|min:0',
        ]);

        $produit = Produit::findOrFail(Produit::keyFromHashId($id));
        $produit->update([
            'designation' => $validated['designation'],
            'fournisseur_id' => $validated['fournisseur_id'] ?? null,
            'prix' => $validated['prix'],
            'prix_vente' => $validated['prix_vente'],
            'unite' => $validated['unite'] ?: null,
        ]);

        $hasStockData = $request->filled('magasin_id')
            && $request->filled('quantite') !== null
            && $request->filled('seuil_alerte') !== null;
        if ($hasStockData) {
            $stock = Stock::firstOrNew([
                'magasin_id' => $validated['magasin_id'],
                'produit_id' => $produit->id,
            ]);
            $stock->quantite = $validated['quantite'];
            $stock->seuil_alerte = $validated['seuil_alerte'];
            $stock->save();
        }

        return redirect()->route('produits.index')->with('success', 'Produit mis à jour avec succès');
    }

    public function destroy(string $id)
    {
        $produit = Produit::findOrFail(Produit::keyFromHashId($id));
        $produit->delete();
        return redirect()->route('produits.index')->with('success', 'Produit supprimé avec succès');
    }
}