<?php

namespace App\Livewire\JobCards;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\JobCard;
use App\Models\Branch;
use App\Models\User;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

class Index extends Component
{
    use WithPagination, AuthorizesRequests;

    public $search = '';
    public $statusFilter = '';
    public $branchFilter = '';
    public $priorityFilter = '';
    public $serviceAdvisorFilter = '';
    public $dateRange = '';
    public $sortBy = 'created_at';
    public $sortDirection = 'desc';

    // Bulk actions
    public $selectedJobCards = [];
    public $selectAll = false;
    public $bulkAction = '';

    // Statistics
    public $statistics = [
        'total' => 0,
        'received' => 0,
        'in_progress' => 0,
        'pending_approval' => 0,
        'completed_today' => 0,
        'delivered_today' => 0,
        'overdue' => 0,
    ];

    protected $queryString = [
        'search' => ['except' => ''],
        'statusFilter' => ['except' => ''],
        'branchFilter' => ['except' => ''],
        'priorityFilter' => ['except' => ''],
        'serviceAdvisorFilter' => ['except' => ''],
        'dateRange' => ['except' => ''],
        'sortBy' => ['except' => 'created_at'],
        'sortDirection' => ['except' => 'desc'],
    ];

    public function boot()
    {
        // Ensure properties are properly initialized
        $this->selectedJobCards = $this->selectedJobCards ?? [];
        $this->statistics = $this->statistics ?? [
            'total' => 0,
            'received' => 0,
            'in_progress' => 0,
            'pending_approval' => 0,
            'completed_today' => 0,
            'delivered_today' => 0,
            'overdue' => 0,
        ];
    }

    public function mount()
    {
        $this->boot(); // Ensure properties are initialized
        $this->authorize('viewAny', JobCard::class);
        
        // Add debug information to debugbar
        if (app()->bound('debugbar')) {
            debugbar()->info('JobCard Index component mounted');
            debugbar()->addMessage('User: ' . auth()->user()->name, 'user');
            debugbar()->addMessage('User permissions checked for JobCard access', 'auth');
        }
        
        $this->loadStatistics();
    }

    public function updatingSearch()
    {
        $this->resetPage();
        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->loadStatistics();
    }

    public function updatingStatusFilter()
    {
        $this->resetPage();
        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->loadStatistics();
    }

    public function updatingBranchFilter()
    {
        $this->resetPage();
        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->loadStatistics();
    }

    public function updatingPriorityFilter()
    {
        $this->resetPage();
        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->loadStatistics();
    }

    public function updatingServiceAdvisorFilter()
    {
        $this->resetPage();
        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->loadStatistics();
    }

    public function updatingDateRange()
    {
        $this->resetPage();
        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->loadStatistics();
    }

    public function sortBy($field)
    {
        if ($this->sortBy === $field) {
            $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortBy = $field;
            $this->sortDirection = 'asc';
        }
        $this->resetPage();
    }

    public function refreshData()
    {
        $this->loadStatistics();
        $this->selectedJobCards = [];
        $this->selectAll = false;
        session()->flash('success', 'Data refreshed successfully.');
    }

    public function clearFilters()
    {
        $this->search = '';
        $this->statusFilter = '';
        $this->branchFilter = '';
        $this->priorityFilter = '';
        $this->serviceAdvisorFilter = '';
        $this->dateRange = '';
        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->resetPage();
        $this->loadStatistics();
        session()->flash('success', 'Filters cleared successfully.');
    }

    /**
     * Get workflow progress percentage for a job card
     */
    public function getWorkflowProgress($status)
    {
        $steps = [
            JobCard::STATUS_RECEIVED => 1,
            JobCard::STATUS_INSPECTED => 2,
            JobCard::STATUS_ASSIGNED_FOR_DIAGNOSIS => 3,
            JobCard::STATUS_IN_DIAGNOSIS => 4,
            JobCard::STATUS_ESTIMATE_SENT => 5,
            JobCard::STATUS_APPROVED => 6,
            JobCard::STATUS_PARTS_PROCUREMENT => 7,
            JobCard::STATUS_IN_PROGRESS => 8,
            JobCard::STATUS_QUALITY_REVIEW_REQUIRED => 9,
            JobCard::STATUS_COMPLETED => 10,
            JobCard::STATUS_DELIVERED => 11,
        ];

        $currentStep = $steps[$status] ?? 1;
        return round(($currentStep / 11) * 100);
    }

    public function loadStatistics()
    {
        try {
            if (app()->bound('debugbar')) {
                debugbar()->startMeasure('statistics', 'Loading JobCard Statistics');
            }
            
            $user = auth()->user();
            $query = JobCard::query();

            // Apply branch filtering based on user permissions
            if (!$user->hasPermission('job-cards.view-all')) {
                if ($user->hasPermission('job-cards.view-own')) {
                    $query->where('service_advisor_id', $user->id);
                } elseif ($user->hasPermission('job-cards.view')) {
                    $query->where('branch_code', $user->branch_code);
                }
            }

            $this->statistics = [
                'total' => $query->count(),
                'received' => (clone $query)->where('status', JobCard::STATUS_RECEIVED)->count(),
                'in_progress' => (clone $query)->whereIn('status', [
                    JobCard::STATUS_IN_DIAGNOSIS,
                    JobCard::STATUS_IN_PROGRESS,
                    JobCard::STATUS_PARTS_PROCUREMENT
                ])->count(),
                'pending_approval' => (clone $query)->where('status', JobCard::STATUS_ESTIMATE_SENT)->count(),
                'completed_today' => (clone $query)->where('status', JobCard::STATUS_COMPLETED)
                    ->whereDate('completion_datetime', today())->count(),
                'delivered_today' => (clone $query)->where('status', JobCard::STATUS_DELIVERED)
                    ->whereDate('completion_datetime', today())->count(),
                'overdue' => (clone $query)->where('expected_completion_date', '<', now())
                    ->whereNotIn('status', [JobCard::STATUS_COMPLETED, JobCard::STATUS_DELIVERED])
                    ->count(),
            ];
            
            if (app()->bound('debugbar')) {
                debugbar()->stopMeasure('statistics');
                debugbar()->addMessage('Statistics loaded: ' . json_encode($this->statistics), 'statistics');
            }
        } catch (\Exception $e) {
            // Fallback statistics if there's an error
            $this->statistics = [
                'total' => 0,
                'received' => 0,
                'in_progress' => 0,
                'pending_approval' => 0,
                'completed_today' => 0,
                'delivered_today' => 0,
                'overdue' => 0,
            ];
            
            if (app()->bound('debugbar')) {
                debugbar()->error('Error loading JobCard statistics: ' . $e->getMessage());
            }
            
            logger()->error('Error loading JobCard statistics: ' . $e->getMessage());
        }
    }

    public function updatedSelectAll()
    {
        if ($this->selectAll) {
            try {
                $this->selectedJobCards = $this->getJobCards()->pluck('id')->toArray();
            } catch (\Exception $e) {
                $this->selectedJobCards = [];
                $this->selectAll = false;
                session()->flash('error', 'Unable to select all job cards. Please try again.');
            }
        } else {
            $this->selectedJobCards = [];
        }
    }

    public function processBulkAction()
    {
        if (empty($this->selectedJobCards) || empty($this->bulkAction)) {
            session()->flash('error', 'Please select job cards and an action.');
            return;
        }

        $successCount = 0;
        $errorCount = 0;

        foreach ($this->selectedJobCards as $jobCardId) {
            try {
                $jobCard = JobCard::find($jobCardId);
                if (!$jobCard) continue;

                switch ($this->bulkAction) {
                    case 'export_csv':
                        return $this->exportSelected();
                        break;
                }
            } catch (\Exception $e) {
                $errorCount++;
            }
        }

        $this->selectedJobCards = [];
        $this->selectAll = false;
        $this->bulkAction = '';
        $this->loadStatistics(); // Refresh statistics after bulk operations

        if ($successCount > 0) {
            session()->flash('success', "{$successCount} job cards processed successfully.");
        }
        if ($errorCount > 0) {
            session()->flash('error', "{$errorCount} job cards failed to process.");
        }
    }

    public function exportSelected()
    {
        if (empty($this->selectedJobCards)) {
            session()->flash('error', 'Please select job cards to export.');
            return;
        }

        $jobCards = JobCard::with(['customer', 'vehicle', 'serviceAdvisor'])
            ->whereIn('id', $this->selectedJobCards)
            ->get();

        $csv = "Job Card Number,Customer,Vehicle,Service Advisor,Status,Priority,Created Date,Expected Completion\n";
        
        foreach ($jobCards as $jobCard) {
            $csv .= sprintf(
                "%s,%s,%s,%s,%s,%s,%s,%s\n",
                $jobCard->job_card_number,
                $jobCard->customer->full_name ?? '',
                $jobCard->vehicle->display_name ?? '',
                $jobCard->serviceAdvisor->name ?? '',
                $jobCard->status,
                $jobCard->priority,
                $jobCard->created_at->format('Y-m-d'),
                $jobCard->expected_completion_date ? $jobCard->expected_completion_date->format('Y-m-d') : ''
            );
        }

        return response()->streamDownload(function () use ($csv) {
            echo $csv;
        }, 'job-cards-' . date('Y-m-d') . '.csv', [
            'Content-Type' => 'text/csv',
        ]);
    }

    protected function getJobCards()
    {
        try {
            $user = auth()->user();
            $query = JobCard::query()
                ->with(['customer', 'vehicle', 'serviceAdvisor']);

            // Apply permission-based filtering
            if (!$user->hasPermission('job-cards.view-all')) {
                if ($user->hasPermission('job-cards.view-own')) {
                    $query->where('service_advisor_id', $user->id);
                } elseif ($user->hasPermission('job-cards.view')) {
                    $query->where('branch_code', $user->branch_code);
                }
            }

            // Apply filters
            if ($this->search) {
                $query->where(function ($q) {
                    $q->where('job_card_number', 'like', '%' . $this->search . '%')
                      ->orWhereHas('customer', function ($customerQuery) {
                          $customerQuery->where('first_name', 'like', '%' . $this->search . '%')
                                      ->orWhere('last_name', 'like', '%' . $this->search . '%')
                                      ->orWhere('email', 'like', '%' . $this->search . '%');
                      })
                      ->orWhereHas('vehicle', function ($vehicleQuery) {
                          $vehicleQuery->where('license_plate', 'like', '%' . $this->search . '%')
                                     ->orWhere('vin', 'like', '%' . $this->search . '%');
                      });
                });
            }

            if ($this->statusFilter) {
                $query->where('status', $this->statusFilter);
            }

            if ($this->branchFilter) {
                $query->where('branch_code', $this->branchFilter);
            }

            if ($this->priorityFilter) {
                $query->where('priority', $this->priorityFilter);
            }

            if ($this->serviceAdvisorFilter) {
                $query->where('service_advisor_id', $this->serviceAdvisorFilter);
            }

            if ($this->dateRange) {
                switch ($this->dateRange) {
                    case 'today':
                        $query->whereDate('created_at', today());
                        break;
                    case 'week':
                        $query->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()]);
                        break;
                    case 'month':
                        $query->whereMonth('created_at', now()->month)
                              ->whereYear('created_at', now()->year);
                        break;
                    case 'overdue':
                        $query->where('expected_completion_date', '<', now())
                              ->whereNotIn('status', [JobCard::STATUS_COMPLETED, JobCard::STATUS_DELIVERED]);
                        break;
                }
            }

            return $query->orderBy($this->sortBy, $this->sortDirection);
        } catch (\Exception $e) {
            logger()->error('Error in getJobCards query: ' . $e->getMessage());
            // Return empty query as fallback
            return JobCard::query()->whereRaw('1 = 0'); // Returns empty result set
        }
    }

    public function render()
    {
        try {
            // Ensure statistics are always fresh and available
            if (empty($this->statistics) || !isset($this->statistics['total'])) {
                $this->loadStatistics();
            }
            
            $jobCards = $this->getJobCards()->paginate(20);

            $statusOptions = JobCard::getStatusOptions();
            
            $priorityOptions = [
                'low' => 'Low',
                'medium' => 'Medium',
                'high' => 'High',
                'urgent' => 'Urgent',
            ];

            $branchOptions = Branch::active()
                ->orderBy('name')
                ->pluck('name', 'code')
                ->toArray();

            $serviceAdvisorOptions = User::whereHas('roles', function ($query) {
                $query->whereIn('name', ['service_advisor', 'service_supervisor']);
            })
            ->where('status', 'active')
            ->orderBy('name')
            ->pluck('name', 'id')
            ->toArray();

            $dateRangeOptions = [
                'today' => 'Today',
                'week' => 'This Week',
                'month' => 'This Month',
                'overdue' => 'Overdue',
            ];

            return view('livewire.job-cards.index', compact(
                'jobCards', 
                'statusOptions', 
                'priorityOptions', 
                'branchOptions',
                'serviceAdvisorOptions',
                'dateRangeOptions'
            ))->with([
                'statistics' => $this->statistics,
                'selectedJobCards' => $this->selectedJobCards ?? [],
                'selectAll' => $this->selectAll ?? false,
                'bulkAction' => $this->bulkAction ?? '',
                'search' => $this->search ?? '',
                'statusFilter' => $this->statusFilter ?? '',
                'branchFilter' => $this->branchFilter ?? '',
                'priorityFilter' => $this->priorityFilter ?? '',
                'serviceAdvisorFilter' => $this->serviceAdvisorFilter ?? '',
                'dateRange' => $this->dateRange ?? '',
                'sortBy' => $this->sortBy ?? 'created_at',
                'sortDirection' => $this->sortDirection ?? 'desc'
            ]);
            
        } catch (\Exception $e) {
            logger()->error('Error rendering JobCard Index: ' . $e->getMessage());
            
            // Provide fallback data
            $jobCards = collect()->paginate(20);
            $statusOptions = [];
            $priorityOptions = [];
            $branchOptions = [];
            $serviceAdvisorOptions = [];
            $dateRangeOptions = [];
            $statistics = $this->statistics ?? [];
            
            session()->flash('error', 'There was an error loading the job cards. Please try again.');
            
            return view('livewire.job-cards.index', compact(
                'jobCards', 
                'statusOptions', 
                'priorityOptions', 
                'branchOptions',
                'serviceAdvisorOptions',
                'dateRangeOptions'
            ))->with([
                'statistics' => $statistics,
                'selectedJobCards' => $this->selectedJobCards ?? [],
                'selectAll' => $this->selectAll ?? false,
                'bulkAction' => $this->bulkAction ?? '',
                'search' => $this->search ?? '',
                'statusFilter' => $this->statusFilter ?? '',
                'branchFilter' => $this->branchFilter ?? '',
                'priorityFilter' => $this->priorityFilter ?? '',
                'serviceAdvisorFilter' => $this->serviceAdvisorFilter ?? '',
                'dateRange' => $this->dateRange ?? ''
            ]);
        }
    }

    /**
     * Handle the component invocation for route compatibility
     */
    public function __invoke()
    {
        return $this->render();
    }
}
