<?php

namespace App\Http\Controllers;

use App\Models\Invoice;
use App\Models\Patient;
use App\Models\User;
use App\Models\Visit;
use Illuminate\Http\Request;

class VisitController extends Controller
{
    public function index(Request $request)
    {
        $this->authorize('viewAny', Visit::class);

        $q = Visit::query()->with(['patient', 'doctor']);

        // Quick search
        if ($search = $request->input('q')) {
            $q->whereHas('patient', function ($query) use ($search) {
                $query->where('full_name', 'like', '%' . $search . '%')
                    ->orWhere('patient_code', 'like', '%' . $search . '%');
            });
        }

        if ($status = $request->input('status')) {
            $q->where('status', $status);
        }

        $visits = $q->latest('visit_date')->paginate(15)->withQueryString();

        return view('visits.index', compact('visits'));
    }

    public function create(Request $request)
    {
        $this->authorize('create', Visit::class);

        $patientId = $request->input('patient_id');
        $patient = null;
        if ($patientId) {
            $patient = Patient::findOrFail($patientId);
            $this->authorize('view', $patient);
        }

        $patients = Patient::where('status', 'active')->orderBy('full_name')->get();
        $doctors = User::where('company_id', auth()->user()->company_id)->get();

        return view('visits.create', compact('patient', 'patients', 'doctors'));
    }

    public function store(Request $request)
    {
        $this->authorize('create', Visit::class);

        $rules = [
            'patient_id' => 'required|exists:patients,id',
            'doctor_id' => 'required|exists:users,id',
            'visit_date' => 'required|date',
            'chief_complaint' => 'required|string',
            'complaint_details' => 'nullable|string',
            'symptoms' => 'nullable|string',
            'diagnosis' => 'nullable|string',
            'examination_notes' => 'nullable|string',
            'blood_pressure' => 'nullable|string',
            'pulse' => 'nullable|string',
            'temperature' => 'nullable|string',
            'weight' => 'nullable|string',
            'height' => 'nullable|string',
            'treatment_plan' => 'nullable|string',
            'prescription_notes' => 'nullable|string',
            'required_tests' => 'nullable|string',
            'required_radiology' => 'nullable|string',
            'follow_up_date' => 'nullable|date',
            'private_notes' => 'nullable|string',
            'status' => 'required|string|in:waiting,in_progress,completed,cancelled',
        ];

        // If automatic invoice creation is requested
        if ($request->boolean('create_invoice')) {
            $rules = array_merge($rules, [
                'consultation_price' => 'required|numeric|min:0',
                'services_total' => 'nullable|numeric|min:0',
                'discount' => 'nullable|numeric|min:0',
                'paid_amount' => 'required|numeric|min:0',
                'payment_method' => 'required|string|in:cash,wallet,card,bank_transfer',
            ]);
        }

        $validated = $request->validate($rules);

        // Check tenancy for patient
        $patient = Patient::findOrFail($validated['patient_id']);
        $this->authorize('view', $patient);

        // Create the visit
        $visit = Visit::create($validated);

        // Handle auto-invoice creation
        if ($request->boolean('create_invoice')) {
            $consultationPrice = (float) $validated['consultation_price'];
            $servicesTotal = (float) ($validated['services_total'] ?? 0.0);
            $discount = (float) ($validated['discount'] ?? 0.0);
            $paidAmount = (float) $validated['paid_amount'];

            $totalAmount = $consultationPrice + $servicesTotal - $discount;
            if ($totalAmount < 0) $totalAmount = 0.0;

            $remainingAmount = $totalAmount - $paidAmount;
            if ($remainingAmount < 0) $remainingAmount = 0.0;

            $paymentStatus = 'unpaid';
            if ($paidAmount > 0) {
                $paymentStatus = $remainingAmount <= 0 ? 'paid' : 'partial';
            }

            Invoice::create([
                'patient_id' => $visit->patient_id,
                'visit_id' => $visit->id,
                'doctor_id' => $visit->doctor_id,
                'consultation_price' => $consultationPrice,
                'services_total' => $servicesTotal,
                'discount' => $discount,
                'total_amount' => $totalAmount,
                'paid_amount' => $paidAmount,
                'remaining_amount' => $remainingAmount,
                'payment_status' => $paymentStatus,
                'payment_method' => $validated['payment_method'],
                'notes' => $request->input('invoice_notes'),
            ]);
        }

        return redirect()->route('patients.show', $visit->patient_id)
            ->with('success', __('clinic.success_message'));
    }

    public function show(Visit $visit)
    {
        $this->authorize('view', $visit);
        $visit->load(['patient', 'doctor', 'invoice']);
        return view('visits.show', compact('visit'));
    }

    public function edit(Visit $visit)
    {
        $this->authorize('update', $visit);
        
        $patients = Patient::where('status', 'active')->orderBy('full_name')->get();
        $doctors = User::where('company_id', auth()->user()->company_id)->get();

        return view('visits.edit', compact('visit', 'patients', 'doctors'));
    }

    public function update(Request $request, Visit $visit)
    {
        $this->authorize('update', $visit);

        $validated = $request->validate([
            'patient_id' => 'required|exists:patients,id',
            'doctor_id' => 'required|exists:users,id',
            'visit_date' => 'required|date',
            'chief_complaint' => 'required|string',
            'complaint_details' => 'nullable|string',
            'symptoms' => 'nullable|string',
            'diagnosis' => 'nullable|string',
            'examination_notes' => 'nullable|string',
            'blood_pressure' => 'nullable|string',
            'pulse' => 'nullable|string',
            'temperature' => 'nullable|string',
            'weight' => 'nullable|string',
            'height' => 'nullable|string',
            'treatment_plan' => 'nullable|string',
            'prescription_notes' => 'nullable|string',
            'required_tests' => 'nullable|string',
            'required_radiology' => 'nullable|string',
            'follow_up_date' => 'nullable|date',
            'private_notes' => 'nullable|string',
            'status' => 'required|string|in:waiting,in_progress,completed,cancelled',
        ]);

        // Check tenancy for patient
        $patient = Patient::findOrFail($validated['patient_id']);
        $this->authorize('view', $patient);

        $visit->update($validated);

        return redirect()->route('visits.show', $visit)
            ->with('success', __('clinic.success_message'));
    }
}
