<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Caution;
use App\Models\Check;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;

class CautionController extends Controller
{
    public function index(Request $request)
    {
        try {
            $this->ensureTableExists();
            $cautions = Caution::with(['check.checkbook'])->orderBy('created_at', 'desc')->paginate(15);

            return response()->json([
                'success' => true,
                'data' => $cautions
            ]);
        } catch (\Exception $e) {
            Log::error('Error fetching cautions: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function store(Request $request)
    {
        try {
            $this->ensureTableExists();
            
            $data = [
                'reference' => $this->generateReference(),
                'market_name' => $request->market_name,
                'amount' => floatval($request->amount),
                'method' => $request->method ?: 'cash',
                'check_id' => $request->method === 'check' ? $request->check_id : null,
                'submission_date' => $request->submission_date,
                'expiry_date' => $request->expiry_date,
                'notification_date' => $request->notification_date,
                'status' => 'active',
                'notes' => $request->notes,
                'user_id' => auth()->id() ?: 1
            ];

            $caution = Caution::create($data);

            // Marquer le chèque comme utilisé pour caution si méthode chèque
            if ($data['method'] === 'check' && $data['check_id']) {
                DB::table('checks')
                    ->where('id', $data['check_id'])
                    ->update(['status' => 'used']);
                Log::info('Check status updated to used for check ID: ' . $data['check_id']);
            }

            return response()->json([
                'success' => true,
                'data' => $caution->load(['check.checkbook'])
            ], 201);
        } catch (\Exception $e) {
            Log::error('Error creating caution: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function show(Caution $caution)
    {
        return response()->json([
            'success' => true,
            'data' => $caution->load(['check.checkbook', 'user'])
        ]);
    }

    public function update(Request $request, Caution $caution)
    {
        try {
            $validated = $request->validate([
                'reference' => 'required|string|max:255',
                'market_name' => 'required|string|max:255',
                'amount' => 'required|numeric|min:0',
                'method' => 'required|in:cash,check',
                'submission_date' => 'required|date',
                'expiry_date' => 'required|date|after:submission_date',
                'notification_date' => 'nullable|date',
                'notes' => 'nullable|string'
            ]);

            $caution->update($validated);

            return response()->json([
                'success' => true,
                'data' => $caution->load(['check.checkbook', 'user'])
            ]);
        } catch (\Exception $e) {
            Log::error('Error updating caution: ' . $e->getMessage());
            return response()->json(['error' => 'Erreur lors de la modification'], 500);
        }
    }

    public function updateStatus(Request $request, Caution $caution)
    {
        try {
            $validated = $request->validate([
                'status' => 'required|in:active,returned,expired,lost'
            ]);

            DB::beginTransaction();

            $caution->update(['status' => $validated['status']]);

            // Si la caution est retournée, libérer le chèque
            if ($validated['status'] === 'returned' && $caution->method === 'check' && $caution->check) {
                $caution->check->update(['status' => 'unused']);
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'data' => $caution->load(['check.checkbook', 'user'])
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error updating caution status: ' . $e->getMessage());
            return response()->json(['error' => 'Erreur lors de la mise à jour du statut'], 500);
        }
    }

    public function destroy(Caution $caution)
    {
        try {
            DB::beginTransaction();

            // Libérer le chèque si la caution est supprimée
            if ($caution->method === 'check' && $caution->check && $caution->check->status === 'caution') {
                $caution->check->update(['status' => 'unused']);
            }

            $caution->delete();

            DB::commit();

            return response()->json(['success' => true]);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error deleting caution: ' . $e->getMessage());
            return response()->json(['error' => 'Erreur lors de la suppression'], 500);
        }
    }

    private function ensureTableExists()
    {
        if (!Schema::hasTable('cautions')) {
            Schema::create('cautions', function (Blueprint $table) {
                $table->id();
                $table->string('reference');
                $table->string('market_name');
                $table->decimal('amount', 15, 2);
                $table->enum('method', ['cash', 'check'])->default('cash');
                $table->unsignedBigInteger('check_id')->nullable();
                $table->date('submission_date');
                $table->date('expiry_date');
                $table->date('notification_date')->nullable();
                $table->enum('status', ['active', 'returned', 'expired', 'lost'])->default('active');
                $table->text('notes')->nullable();
                $table->unsignedBigInteger('user_id');
                $table->timestamps();
            });
        }
    }

    private function generateReference()
    {
        $year = date('Y');
        $lastCaution = Caution::whereYear('created_at', $year)->orderBy('id', 'desc')->first();
        $number = $lastCaution ? (intval(substr($lastCaution->reference, -4)) + 1) : 1;
        return 'CAU-' . $year . '-' . str_pad($number, 4, '0', STR_PAD_LEFT);
    }
}