<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Payment;
use App\Models\Invoice;
use App\Models\Check;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class PaymentController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        try {
            $query = Payment::with(['client', 'supplier', 'invoice', 'user']);

            if ($request->has('type') && $request->get('type')) {
                $direction = $request->get('type') === 'received' ? 'in' : 'out';
                $query->where('direction', $direction);
            }

            if ($request->has('method') && $request->get('method')) {
                $query->where('method', $request->get('method'));
            }

            if ($request->has('search') && $request->get('search')) {
                $search = $request->get('search');
                $query->where('number', 'like', "%{$search}%");
            }

            $payments = $query->orderBy('created_at', 'desc')
                             ->paginate($request->get('per_page', 15));
            
            return response()->json($payments);
        } catch (\Exception $e) {
            \Log::error('Erreur chargement règlements: ' . $e->getMessage());
            return response()->json(['error' => 'Erreur lors du chargement des règlements: ' . $e->getMessage()], 500);
        }
    }
    
    private function ensurePaymentColumns()
    {
        try {
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS type VARCHAR(50) DEFAULT 'received'");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS method VARCHAR(50) DEFAULT 'cash'");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS reference VARCHAR(255)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS client_id INTEGER REFERENCES clients(id)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS supplier_id INTEGER REFERENCES suppliers(id)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS invoice_id INTEGER REFERENCES invoices(id)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS user_id INTEGER REFERENCES users(id)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS check_id INTEGER REFERENCES checks(id)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS check_number VARCHAR(255)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS bank_name VARCHAR(255)");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS notes TEXT");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS date DATE DEFAULT CURRENT_DATE");
            \DB::statement("ALTER TABLE payments ADD COLUMN IF NOT EXISTS amount DECIMAL(10,2) DEFAULT 0");
        } catch (\Exception $e) {
            // Ignorer les erreurs si les colonnes existent déjà
        }
    }

    public function store(Request $request): JsonResponse
    {
        try {
            // Créer les colonnes manquantes si nécessaire
            $this->ensurePaymentColumns();
            
            $validated = $request->validate([
            'type' => 'required|in:received,sent',
            'date' => 'required|date',
            'amount' => 'required|numeric|min:0.01',
            'method' => 'required|in:cash,check,transfer,card',
            'reference' => 'nullable|string|max:255',
            'client_id' => 'nullable|exists:clients,id',
            'supplier_id' => 'nullable|exists:suppliers,id',
            'invoice_id' => 'nullable|exists:invoices,id',
            'check_id' => 'nullable|exists:checks,id',
            'check_number' => 'nullable|string|max:255',
            'bank_name' => 'nullable|string|max:255',
            'notes' => 'nullable|string',
        ]);

        // Validation logique
        if ($validated['type'] === 'received' && !$validated['client_id']) {
            return response()->json(['error' => 'Un client est requis pour un règlement reçu'], 400);
        }

        if ($validated['type'] === 'sent' && !$validated['supplier_id']) {
            return response()->json(['error' => 'Un fournisseur est requis pour un règlement envoyé'], 400);
        }

        // Si un chèque est sélectionné, le marquer comme utilisé
        if ($validated['check_id']) {
            $check = Check::find($validated['check_id']);
            if ($check) {
                $check->update([
                    'status' => 'used',
                    'amount' => $validated['amount'],
                    'payee' => $validated['type'] === 'received' ? 'Client' : 'Fournisseur',
                    'issue_date' => $validated['date'],
                ]);
            }
        }

        // Générer un numéro unique pour le règlement
        $prefix = $validated['type'] === 'received' ? 'REG-' : 'PAY-';
        $year = date('Y');
        $lastPayment = Payment::where('number', 'like', $prefix . $year . '-%')
                             ->orderBy('number', 'desc')
                             ->first();
        
        $nextNumber = 1;
        if ($lastPayment) {
            $lastNumber = (int) substr($lastPayment->number, -4);
            $nextNumber = $lastNumber + 1;
        }
        
        $paymentNumber = $prefix . $year . '-' . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);

        $payment = Payment::create([
            'number' => $paymentNumber,
            'type' => $validated['method'], // La contrainte attend le type de paiement (cash, check, etc.)
            'direction' => $validated['type'] === 'received' ? 'in' : 'out',
            'date' => $validated['date'],
            'amount' => $validated['amount'],
            'method' => $validated['method'],
            'reference' => $validated['reference'],
            'client_id' => $validated['client_id'],
            'supplier_id' => $validated['supplier_id'],
            'invoice_id' => $validated['invoice_id'],
            'check_id' => $validated['check_id'],
            'check_number' => $validated['check_number'],
            'bank_name' => $validated['bank_name'],
            'user_id' => auth()->id(),
            'notes' => $validated['notes'],
        ]);

        // Mettre à jour la facture si spécifiée
        if ($validated['invoice_id']) {
            $invoice = Invoice::find($validated['invoice_id']);
            if ($invoice) {
                $newPaidAmount = $invoice->paid_amount + $validated['amount'];
                $newRemainingAmount = $invoice->total_ttc - $newPaidAmount;
                
                $invoice->update([
                    'paid_amount' => $newPaidAmount,
                    'remaining_amount' => $newRemainingAmount,
                    'status' => $newRemainingAmount <= 0 ? 'paid' : 'partially_paid',
                ]);
            }
        }

            return response()->json($payment->load(['client', 'supplier', 'invoice', 'check']), 201);
        } catch (\Exception $e) {
            \Log::error('Erreur sauvegarde règlement: ' . $e->getMessage());
            return response()->json(['error' => 'Erreur lors de la sauvegarde du règlement: ' . $e->getMessage()], 500);
        }
    }

    public function show(Payment $payment): JsonResponse
    {
        return response()->json($payment->load(['client', 'supplier', 'invoice', 'user']));
    }

    public function update(Request $request, Payment $payment): JsonResponse
    {
        $validated = $request->validate([
            'type' => 'required|in:received,sent',
            'date' => 'required|date',
            'amount' => 'required|numeric|min:0.01',
            'method' => 'required|in:cash,check,transfer,card',
            'reference' => 'nullable|string|max:255',
            'client_id' => 'nullable|exists:clients,id',
            'supplier_id' => 'nullable|exists:suppliers,id',
            'invoice_id' => 'nullable|exists:invoices,id',
            'notes' => 'nullable|string',
        ]);

        // Restaurer l'ancien montant de la facture
        if ($payment->invoice_id) {
            $oldInvoice = Invoice::find($payment->invoice_id);
            if ($oldInvoice) {
                $newPaidAmount = $oldInvoice->paid_amount - $payment->amount;
                $newRemainingAmount = $oldInvoice->total_ttc - $newPaidAmount;
                
                $oldInvoice->update([
                    'paid_amount' => $newPaidAmount,
                    'remaining_amount' => $newRemainingAmount,
                    'status' => $newRemainingAmount <= 0 ? 'paid' : ($newPaidAmount > 0 ? 'partially_paid' : 'sent'),
                ]);
            }
        }

        $payment->update($validated);

        // Appliquer le nouveau montant à la facture
        if ($validated['invoice_id']) {
            $invoice = Invoice::find($validated['invoice_id']);
            if ($invoice) {
                $newPaidAmount = $invoice->paid_amount + $validated['amount'];
                $newRemainingAmount = $invoice->total_ttc - $newPaidAmount;
                
                $invoice->update([
                    'paid_amount' => $newPaidAmount,
                    'remaining_amount' => $newRemainingAmount,
                    'status' => $newRemainingAmount <= 0 ? 'paid' : 'partially_paid',
                ]);
            }
        }

        return response()->json($payment->load(['client', 'supplier', 'invoice']));
    }

    public function destroy(Payment $payment): JsonResponse
    {
        // Restaurer le montant de la facture
        if ($payment->invoice_id) {
            $invoice = Invoice::find($payment->invoice_id);
            if ($invoice) {
                $newPaidAmount = $invoice->paid_amount - $payment->amount;
                $newRemainingAmount = $invoice->total_ttc - $newPaidAmount;
                
                $invoice->update([
                    'paid_amount' => $newPaidAmount,
                    'remaining_amount' => $newRemainingAmount,
                    'status' => $newRemainingAmount <= 0 ? 'paid' : ($newPaidAmount > 0 ? 'partially_paid' : 'sent'),
                ]);
            }
        }

        $payment->delete();
        return response()->json(['message' => 'Règlement supprimé avec succès']);
    }
}