<?php

namespace App\Http\Controllers\BloodBank;

use App\Models\BloodBank\BloodBank;
use App\Models\BloodBank\BloodInventory;
use App\Models\BloodBank\BloodRequest;
use App\Models\BloodBank\BloodDonation;
use App\Models\BloodBank\BloodDrive;
use App\Models\BloodBank\DriveRegistration;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Routing\Controller;
use Barryvdh\Debugbar\Controllers\BaseController;

class PublicBloodBankController extends Controller
{
    /**
     * Display the blood bank homepage
     */
    public function index()
    {
        // Get blood availability
        $bloodTypes = ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-'];
        $bloodInventory = [];
        
        foreach ($bloodTypes as $type) {
            $units = BloodInventory::where('blood_type', $type)->sum('units_available');
            $status = 'success';
            
            if ($units <= 5) {
                $status = 'danger';
            } elseif ($units <= 10) {
                $status = 'warning';
            }
            
            $bloodInventory[$type] = [
                'units' => $units,
                'status' => $status
            ];
        }
        
        // Get recent blood requests
        $recentRequests = BloodRequest::with('user')
            ->where('status', '!=', 'fulfilled')
            ->where('is_public', true)
            ->where('needed_by', '>=', now())
            ->orderBy('urgency', 'desc')
            ->orderBy('created_at', 'desc')
            ->take(2)
            ->get();
            
        // Get emergency request (if any)
        $emergencyRequest = BloodRequest::where('urgency', 'emergency')
            ->where('status', '!=', 'fulfilled')
            ->where('is_public', true)
            ->where('needed_by', '>=', now())
            ->orderBy('created_at', 'desc')
            ->first();
            
        // Get upcoming blood drives
        $upcomingDrives = BloodDrive::with('registrations')
            ->where('start_datetime', '>', now())
            ->orderBy('start_datetime')
            ->take(1)
            ->get();
            
        // Get nearby donors if user is authenticated and has location
        $nearbyDonors = collect();
        if (Auth::check() && Auth::user()->latitude && Auth::user()->longitude) {
            $nearbyDonors = User::where('is_donor', true)
                ->where('show_as_donor', true)
                ->where('id', '!=', Auth::id())
                ->selectRaw("*, (
                    6371 * acos(
                        cos(radians(?)) * cos(radians(latitude)) * cos(radians(longitude) - radians(?)) + 
                        sin(radians(?)) * sin(radians(latitude))
                    )
                ) AS distance", [Auth::user()->latitude, Auth::user()->longitude, Auth::user()->latitude])
                ->having('distance', '<=', 10)
                ->orderBy('distance')
                ->take(4)
                ->get();
        }
        
        return view('front_end.pages.bloodbank.index', compact(
            'bloodInventory',
            'recentRequests',
            'emergencyRequest',
            'upcomingDrives',
            'nearbyDonors'
        ));
    }
    
    /**
     * Display blood donation page
     */
    public function donate()
    {
        // Check if user is authenticated
        if (!Auth::check()) {
            return redirect()->route('login')
                ->with('error', 'Please login to schedule a donation');
        }
        
        // Check if user has blood type set
        $user = Auth::user();
        if (!$user->blood_type) {
            return redirect()->route('bloodbank.profile')
                ->with('error', 'Please set your blood type before scheduling a donation');
        }
        
        // Get blood banks for selection
        $bloodBanks = BloodBank::all();
        
        // Get active blood requests matching user's blood type
        $compatibleRequests = BloodRequest::with('user')
            ->where('status', '!=', 'fulfilled')
            ->where('is_public', true)
            ->where('needed_by', '>=', now())
            ->where(function($query) use ($user) {
                // Blood type compatibility logic
                if ($user->blood_type == 'O-') {
                    // O- can donate to all types
                    return $query;
                } elseif ($user->blood_type == 'O+') {
                    // O+ can donate to O+, A+, B+, AB+
                    return $query->whereIn('blood_type', ['O+', 'A+', 'B+', 'AB+']);
                } elseif ($user->blood_type == 'A-') {
                    // A- can donate to A-, A+, AB-, AB+
                    return $query->whereIn('blood_type', ['A-', 'A+', 'AB-', 'AB+']);
                } elseif ($user->blood_type == 'A+') {
                    // A+ can donate to A+, AB+
                    return $query->whereIn('blood_type', ['A+', 'AB+']);
                } elseif ($user->blood_type == 'B-') {
                    // B- can donate to B-, B+, AB-, AB+
                    return $query->whereIn('blood_type', ['B-', 'B+', 'AB-', 'AB+']);
                } elseif ($user->blood_type == 'B+') {
                    // B+ can donate to B+, AB+
                    return $query->whereIn('blood_type', ['B+', 'AB+']);
                } elseif ($user->blood_type == 'AB-') {
                    // AB- can donate to AB-, AB+
                    return $query->whereIn('blood_type', ['AB-', 'AB+']);
                } else {
                    // AB+ can only donate to AB+
                    return $query->where('blood_type', 'AB+');
                }
            })
            ->orderBy('urgency', 'desc')
            ->orderBy('created_at', 'desc')
            ->get();
            
        // Get user's donation history
        $donationHistory = BloodDonation::with(['bloodBank', 'request'])
            ->where('user_id', Auth::id())
            ->orderBy('donation_date', 'desc')
            ->take(5)
            ->get();
            
        // Check if user is eligible to donate
        $isEligible = $user->isEligibleToDonate();
        $nextEligibleDate = null;
        
        if (!$isEligible && $user->last_donation_date) {
            $nextEligibleDate = $user->last_donation_date->addDays(56);
        }
        
        return view('front_end.pages.bloodbank.donate', compact(
            'bloodBanks',
            'compatibleRequests',
            'donationHistory',
            'isEligible',
            'nextEligibleDate'
        ));
    }
    
    /**
     * Display blood request page
     */
    public function request()
    {
        // Check if user is authenticated
        if (!Auth::check()) {
            return redirect()->route('login')
                ->with('error', 'Please login to submit a blood request');
        }
        
        // Get hospitals (blood banks) for selection
        $hospitals = BloodBank::all();
        
        // Get user's active requests
        $activeRequests = BloodRequest::where('user_id', Auth::id())
            ->where('status', '!=', 'fulfilled')
            ->where('status', '!=', 'cancelled')
            ->where('needed_by', '>=', now())
            ->orderBy('created_at', 'desc')
            ->get();
            
        // Get recent responses to user's requests
        $recentResponses = BloodDonation::with(['user', 'request'])
            ->whereHas('request', function($query) {
                $query->where('user_id', Auth::id());
            })
            ->orderBy('created_at', 'desc')
            ->take(5)
            ->get();
            
        return view('front_end.pages.bloodbank.request', compact(
            'hospitals',
            'activeRequests',
            'recentResponses'
        ));
    }
    
    /**
     * Display blood requests list
     */
    public function requests()
    {
        // Get active requests
        $requests = BloodRequest::with('user')
            ->where('status', '!=', 'fulfilled')
            ->where('status', '!=', 'cancelled')
            ->where('is_public', true)
            ->where('needed_by', '>=', now())
            ->orderBy('urgency', 'desc')
            ->orderBy('created_at', 'desc')
            ->paginate(10);
            
        return view('front_end.pages.bloodbank.requests', compact('requests'));
    }
    
    /**
     * Display blood request detail
     */
    public function requestDetail($id)
    {
        $request = BloodRequest::with(['user', 'donations.user'])
            ->findOrFail($id);
            
        // Check if request is public or belongs to the authenticated user
        if (!$request->is_public && (!Auth::check() || $request->user_id !== Auth::id())) {
            abort(403, 'You do not have permission to view this request');
        }
        
        // Check if user can donate to this request (blood type compatibility)
        $canDonate = false;
        $compatibilityMessage = "";
        
        if (Auth::check() && Auth::user()->blood_type) {
            $userBloodType = Auth::user()->blood_type;
            $requestBloodType = $request->blood_type;
            
            // Blood type compatibility logic
            if ($userBloodType == 'O-') {
                // O- can donate to all types
                $canDonate = true;
            } elseif ($userBloodType == 'O+' && in_array($requestBloodType, ['O+', 'A+', 'B+', 'AB+'])) {
                $canDonate = true;
            } elseif ($userBloodType == 'A-' && in_array($requestBloodType, ['A-', 'A+', 'AB-', 'AB+'])) {
                $canDonate = true;
            } elseif ($userBloodType == 'A+' && in_array($requestBloodType, ['A+', 'AB+'])) {
                $canDonate = true;
            } elseif ($userBloodType == 'B-' && in_array($requestBloodType, ['B-', 'B+', 'AB-', 'AB+'])) {
                $canDonate = true;
            } elseif ($userBloodType == 'B+' && in_array($requestBloodType, ['B+', 'AB+'])) {
                $canDonate = true;
            } elseif ($userBloodType == 'AB-' && in_array($requestBloodType, ['AB-', 'AB+'])) {
                $canDonate = true;
            } elseif ($userBloodType == 'AB+' && $requestBloodType == 'AB+') {
                $canDonate = true;
            }
            
            if (!$canDonate) {
                $compatibilityMessage = "Your blood type {$userBloodType} is not compatible with the requested blood type {$requestBloodType}";
            } elseif (Auth::user()->last_donation_date && !Auth::user()->isEligibleToDonate()) {
                $canDonate = false;
                $nextEligible = Auth::user()->last_donation_date->addDays(56)->format('Y-m-d');
                $compatibilityMessage = "You're not eligible to donate until {$nextEligible}";
            }
        }
        
        return view('front_end.pages.bloodbank.request-detail', compact(
            'request',
            'canDonate',
            'compatibilityMessage'
        ));
    }
    
    /**
     * Display blood drives list
     */
    public function drives()
    {
        // Get upcoming blood drives
        $upcomingDrives = BloodDrive::with(['bloodBank', 'registrations'])
            ->where('end_datetime', '>=', now())
            ->orderBy('start_datetime')
            ->paginate(6);
            
        // Get user's registered drives
        $userRegistrations = collect();
        if (Auth::check()) {
            $userRegistrations = DriveRegistration::with('bloodDrive')
                ->where('user_id', Auth::id())
                ->whereHas('bloodDrive', function($query) {
                    $query->where('end_datetime', '>=', now());
                })
                ->get()
                ->pluck('blood_drive_id');
        }
        
        return view('front_end.pages.bloodbank.drives', compact(
            'upcomingDrives',
            'userRegistrations'
        ));
    }
    
    /**
     * Display blood drive detail
     */
    public function driveDetail($id)
    {
        $drive = BloodDrive::with(['bloodBank', 'registrations.user'])
            ->findOrFail($id);
            
        // Check if user is registered
        $isRegistered = false;
        if (Auth::check()) {
            $isRegistered = DriveRegistration::where('blood_drive_id', $id)
                ->where('user_id', Auth::id())
                ->exists();
        }
        
        // Check if registration is full
        $isRegistrationFull = $drive->isRegistrationFull();
        
        // Check if drive is in the past
        $isPast = $drive->end_datetime->isPast();
        
        return view('front_end.pages.bloodbank.drive-detail', compact(
            'drive',
            'isRegistered',
            'isRegistrationFull',
            'isPast'
        ));
    }
    
    /**
     * Display donor profile page
     */
    public function profile()
    {
        // Check if user is authenticated
        if (!Auth::check()) {
            return redirect()->route('login')
                ->with('error', 'Please login to view your donor profile');
        }
        
        $user = Auth::user();
      
        // Get donation statistics
        $totalDonations = BloodDonation::where('user_id', $user->id)
            ->where('status', 'completed')
            ->count();
            
        $totalUnits = BloodDonation::where('user_id', $user->id)
            ->where('status', 'completed')
            ->sum('units');
            
        // Get upcoming donations
        $upcomingDonations = BloodDonation::with(['bloodBank', 'request'])
            ->where('user_id', $user->id)
            ->where('status', 'scheduled')
            ->where('donation_date', '>=', now())
            ->orderBy('donation_date')
            ->get();
            
        // Get donation history
        $donationHistory = BloodDonation::with(['bloodBank', 'request'])
            ->where('user_id', $user->id)
            ->where('status', 'completed')
            ->orderBy('donation_date', 'desc')
            ->paginate(5);
            
        // Check eligibility
        $isEligible = $user->isEligibleToDonate();
        $nextEligibleDate = null;
        
        if (!$isEligible && $user->last_donation_date) {
            $nextEligibleDate = $user->last_donation_date->addDays(56);
        }
        
        return view('front_end.pages.bloodbank.profile', compact(
            'user',
            'totalDonations',
            'totalUnits',
            'upcomingDonations',
            'donationHistory',
            'isEligible',
            'nextEligibleDate'
        ));
    }
    
    /**
     * Display nearby donors
     */
    public function donors()
    {
        // Check if user is authenticated and has location
        if (!Auth::check()) {
            return redirect()->route('login')
                ->with('error', 'Please login to view nearby donors');
        }
        
        $user = Auth::user();
        // if (!$user->latitude || !$user->longitude) {
        //     return redirect()->route('bloodbank.profile')
        //         ->with('error', 'Please set your location to view nearby donors');
        // }
        
        // Get nearby donors
        $donors = $user->getNearbyDonors(null, 25);
        
        // Group donors by blood type
        $donorsByBloodType = $donors->groupBy('blood_type');
        
        return view('front_end.pages.bloodbank.donors', compact(
            'donors',
            'donorsByBloodType'
        ));
    }
}