<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Budget;
use App\Models\BudgetItem;
use App\Models\MedicalService;
use App\Models\Patients;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Jobs\SendBudgetEmail;
use App\Exceptions\GlobalException;
use DateTime;

class BudgetController extends Controller
{
    public function index()
    {
        $budgets = Budget::with(['patient', 'creator'])->get();
        return view('budgets.index', compact('budgets'));
    }

    public function create()
    {
        $patients = Patients::all();
        $services = MedicalService::where('is_active', true)->get();
        return view('budgets.create', compact('patients', 'services'));
    }

    public function store(Request $request)
    {
        try {


            $validated = $request->validate([
                'patients_id' => 'required|exists:patients,id',
                'notes' => 'nullable|string',
                'tax_percentage' => 'required|numeric|min:0|max:100',
                'items' => 'required|array|min:1',
                'items.*.medical_service_id' => 'required|exists:medical_services,id',
                'items.*.quantity' => 'required|integer|min:1',
                'items.*.notes' => 'nullable|string'
            ]);

            // Crear el presupuesto con ID único
            $budget = new Budget();
            $budget->id = md5(uniqid(rand(), true));
            $budget->code = Budget::generateCode();
            $budget->patients_id = $validated['patients_id'];
            $budget->notes = $validated['notes'];
            $budget->tax_percentage = $validated['tax_percentage'];
            $budget->created_by = Auth::id();
            $budget->save();

            // Crear los items con IDs únicos
            foreach ($validated['items'] as $item) {
                $service = MedicalService::find($item['medical_service_id']);
                
                $budgetItem = new BudgetItem();
                $budgetItem->id = md5(uniqid(rand(), true));
                $budgetItem->budget_id = $budget->id;
                $budgetItem->medical_service_id = $service->id;
                $budgetItem->quantity = $item['quantity'];
                $budgetItem->price = $service->cost;
                $budgetItem->subtotal = $service->cost * $item['quantity'];
                $budgetItem->notes = $item['notes'] ?? null;
                $budgetItem->save();
            }

            // Calcular el total del presupuesto
            $budget->calculateTotal();

            // Enviar correo a través del Job si el paciente tiene email
            if ($budget->patient->email) {
                SendBudgetEmail::dispatch($budget);
            }

            return redirect()->route('budgets.show', $budget)
                ->with('success', 'Presupuesto creado exitosamente');

        } catch (\Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }

    public function show(Budget $budget)
    {
        $budget->load(['patient', 'items.medicalService', 'creator']);
        return view('budgets.show', compact('budget'));
    }

    public function edit(Budget $budget)
    {
        if ($budget->status !== 'draft') {
            return redirect()->route('budgets.show', $budget)
                ->with('error', 'Solo se pueden editar presupuestos en borrador');
        }

        $patients = Patients::all();
        $services = MedicalService::where('is_active', true)->get();
        return view('budgets.edit', compact('budget', 'patients', 'services'));
    }

    public function update(Request $request, Budget $budget)
    {
        try {
            if ($budget->status !== 'draft') {
                return redirect()->route('budgets.show', $budget)
                    ->with('error', 'Solo se pueden editar presupuestos en borrador');
            }

            $validated = $request->validate([
                'patients_id' => 'required|exists:patients,id',
                'notes' => 'nullable|string',
                'tax_percentage' => 'required|numeric|min:0|max:100',
                'items' => 'required|array|min:1',
                'items.*.medical_service_id' => 'required|exists:medical_services,id',
                'items.*.quantity' => 'required|integer|min:1',
                'items.*.notes' => 'nullable|string'
            ]);

            // Actualizar presupuesto
            $budget->patients_id = $validated['patients_id'];
            $budget->notes = $validated['notes'];
            $budget->tax_percentage = $validated['tax_percentage'];
            $budget->save();

            // Eliminar items anteriores
            $budget->items()->delete();

            // Crear nuevos items con IDs únicos
            foreach ($validated['items'] as $item) {
                $service = MedicalService::find($item['medical_service_id']);
                
                $budgetItem = new BudgetItem();
                $budgetItem->id = md5(uniqid(rand(), true));
                $budgetItem->budget_id = $budget->id;
                $budgetItem->medical_service_id = $service->id;
                $budgetItem->quantity = $item['quantity'];
                $budgetItem->price = $service->cost;
                $budgetItem->subtotal = $service->cost * $item['quantity'];
                $budgetItem->notes = $item['notes'] ?? null;
                $budgetItem->save();
            }

            // Calcular el total del presupuesto
            $budget->calculateTotal();

            // Cargar las relaciones necesarias
            $budget->load(['patient', 'items.medicalService', 'creator']);

            return redirect()->route('budgets.show', $budget)
                ->with('success', 'Presupuesto actualizado exitosamente');

        } catch (\Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }

    public function destroy(Budget $budget)
    {
        try {
            $budget->delete();
            return redirect()->route('budgets.index')
                ->with('success', 'Presupuesto eliminado exitosamente');
        } catch (\Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }

    public function send(Budget $budget)
    {
        try {
            if (!$budget->patient->email) {
                return redirect()->route('budgets.show', $budget)
                    ->with('error', 'El paciente no tiene un correo electrónico registrado');
            }

            // Enviar correo a través del Job
            SendBudgetEmail::dispatch($budget);

            return redirect()->route('budgets.show', $budget)
                ->with('success', 'Presupuesto enviado exitosamente');

        } catch (\Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }

    public function approve(Budget $budget)
    {
        try {
            if ($budget->status !== 'sent') {
                return redirect()->route('budgets.show', $budget)
                    ->with('error', 'Solo se pueden aprobar presupuestos en estado enviado');
            }

            $budget->status = 'approved';
            $budget->save();

            return redirect()->route('budgets.show', $budget)
                ->with('success', 'Presupuesto aprobado exitosamente');

        } catch (\Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }

    public function reject(Budget $budget)
    {
        try {
            if ($budget->status !== 'sent') {
                return redirect()->route('budgets.show', $budget)
                    ->with('error', 'Solo se pueden rechazar presupuestos en estado enviado');
            }

            $budget->status = 'rejected';
            $budget->save();

            return redirect()->route('budgets.show', $budget)
                ->with('success', 'Presupuesto rechazado exitosamente');

        } catch (\Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }
} 