<?php

namespace App\Services;

use App\Models\JobCard;
use App\Models\Estimate;
use App\Models\WorkOrder;
use App\Models\Diagnosis;
use App\Models\VehicleInspection;
use App\Models\User;
use Illuminate\Support\Facades\DB;

class WorkflowService
{
    public function __construct(
        private NotificationService $notificationService
    ) {}

    /**
     * Create job card when vehicle arrives
     */
    public function createJobCard(array $data): JobCard
    {
        return DB::transaction(function () use ($data) {
            $jobCard = JobCard::create([
                'customer_id' => $data['customer_id'],
                'vehicle_id' => $data['vehicle_id'],
                'service_advisor_id' => $data['service_advisor_id'],
                'branch_code' => $data['branch_code'] ?? config('app.default_branch_code', 'ACC'),
                'arrival_datetime' => $data['arrival_datetime'],
                'mileage_in' => $data['mileage_in'],
                'fuel_level_in' => $data['fuel_level_in'],
                'customer_reported_issues' => $data['customer_reported_issues'],
                'vehicle_condition_notes' => $data['vehicle_condition_notes'],
                'keys_location' => $data['keys_location'],
                'personal_items_removed' => $data['personal_items_removed'] ?? false,
                'photos_taken' => $data['photos_taken'] ?? false,
                'expected_completion_date' => $data['expected_completion_date'] ?? null,
                'priority' => $data['priority'] ?? 'medium',
                'notes' => $data['notes'] ?? null,
            ]);

            // Create incoming inspection checklist
            if (isset($data['inspection_checklist'])) {
                VehicleInspection::create([
                    'job_card_id' => $jobCard->id,
                    'vehicle_id' => $jobCard->vehicle_id,
                    'inspector_id' => $data['inspector_id'],
                    'inspection_type' => 'incoming',
                    'current_mileage' => $data['mileage_in'],
                    'fuel_level' => $data['fuel_level_in'],
                    'inspection_checklist' => $data['inspection_checklist'],
                    'photos' => $data['inspection_photos'] ?? [],
                    'overall_condition' => $data['overall_condition'],
                    'inspection_date' => now(),
                    'notes' => $data['inspection_notes'] ?? null,
                ]);
            }

            return $jobCard;
        });
    }

    /**
     * Assign job card to service coordinator and start diagnosis
     */
    public function assignToServiceCoordinator(JobCard $jobCard, int $serviceCoordinatorId): Diagnosis
    {
        $diagnosis = Diagnosis::create([
            'job_card_id' => $jobCard->id,
            'service_coordinator_id' => $serviceCoordinatorId,
            'customer_reported_issues' => $jobCard->customer_reported_issues,
            'diagnosis_status' => 'in_progress',
            'diagnosis_date' => now(),
        ]);

        $jobCard->update(['status' => 'in_diagnosis']);

        return $diagnosis;
    }

    /**
     * Complete diagnosis and create estimate
     */
    public function completeDiagnosis(Diagnosis $diagnosis, array $diagnosisData, array $estimateItems): Estimate
    {
        return DB::transaction(function () use ($diagnosis, $diagnosisData, $estimateItems) {
            // Update diagnosis
            $diagnosis->update([
                'diagnostic_findings' => $diagnosisData['diagnostic_findings'],
                'root_cause_analysis' => $diagnosisData['root_cause_analysis'],
                'recommended_repairs' => $diagnosisData['recommended_repairs'],
                'additional_issues_found' => $diagnosisData['additional_issues_found'] ?? null,
                'priority_level' => $diagnosisData['priority_level'] ?? 'medium',
                'estimated_repair_time' => $diagnosisData['estimated_repair_time'],
                'parts_required' => $diagnosisData['parts_required'] ?? [],
                'labor_operations' => $diagnosisData['labor_operations'] ?? [],
                'special_tools_required' => $diagnosisData['special_tools_required'] ?? [],
                'safety_concerns' => $diagnosisData['safety_concerns'] ?? null,
                'customer_authorization_required' => $diagnosisData['customer_authorization_required'] ?? false,
                'diagnosis_status' => 'completed',
                'notes' => $diagnosisData['notes'] ?? null,
            ]);

            // Create estimate
            $estimate = Estimate::create([
                'job_card_id' => $diagnosis->job_card_id,
                'diagnosis_id' => $diagnosis->id,
                'prepared_by_id' => $diagnosis->service_coordinator_id,
                'tax_rate' => config('app.default_tax_rate', 8.25),
                'validity_period_days' => 30,
                'terms_and_conditions' => config('app.default_estimate_terms'),
                'status' => 'draft',
            ]);

            // Add estimate line items
            foreach ($estimateItems as $item) {
                $estimate->lineItems()->create($item);
            }

            // Calculate totals
            $estimate->calculateTotals();

            // Update job card status
            $diagnosis->jobCard->update(['status' => 'estimate_sent']);

            return $estimate;
        });
    }

    /**
     * Send estimate to customer
     */
    public function sendEstimateToCustomer(Estimate $estimate): void
    {
        $this->notificationService->sendEstimateToCustomer($estimate);
    }

    /**
     * Approve estimate and create work order
     */
    public function approveEstimate(Estimate $estimate, string $approvalMethod = 'portal'): WorkOrder
    {
        return DB::transaction(function () use ($estimate, $approvalMethod) {
            // Update estimate
            $estimate->update([
                'customer_approval_status' => 'approved',
                'customer_approved_at' => now(),
                'customer_approval_method' => $approvalMethod,
                'status' => 'approved',
            ]);

            // Update job card
            $estimate->jobCard->update(['status' => 'approved']);

            // Send notifications
            $this->notificationService->notifyEstimateApproved($estimate);

            // Create work order
            $workOrder = WorkOrder::create([
                'job_card_id' => $estimate->job_card_id,
                'estimate_id' => $estimate->id,
                'service_coordinator_id' => $estimate->diagnosis->service_coordinator_id,
                'priority' => $estimate->jobCard->priority,
                'work_description' => $estimate->diagnosis->recommended_repairs,
                'special_instructions' => $estimate->diagnosis->notes,
                'quality_check_required' => true,
                'status' => 'pending',
            ]);

            return $workOrder;
        });
    }

    /**
     * Assign work order to technician and start work
     */
    public function assignWorkOrder(WorkOrder $workOrder, int $technicianId): void
    {
        $workOrder->update([
            'assigned_technician_id' => $technicianId,
            'status' => 'assigned',
            'actual_start_time' => now(),
        ]);

        $workOrder->jobCard->update(['status' => 'in_progress']);
    }

    /**
     * Complete work order and perform quality check
     */
    public function completeWorkOrder(WorkOrder $workOrder, int $qualityCheckerId): void
    {
        $workOrder->update([
            'status' => 'quality_check',
            'actual_completion_time' => now(),
            'quality_checked_by_id' => $qualityCheckerId,
            'quality_check_date' => now(),
            'completion_percentage' => 100,
        ]);
    }

    /**
     * Perform outgoing inspection and final quality check
     */
    public function performOutgoingInspection(JobCard $jobCard, array $inspectionData, int $inspectorId): void
    {
        // Create outgoing inspection
        $outgoingInspection = VehicleInspection::create([
            'job_card_id' => $jobCard->id,
            'vehicle_id' => $jobCard->vehicle_id,
            'inspector_id' => $inspectorId,
            'inspection_type' => 'outgoing',
            'current_mileage' => $inspectionData['mileage_out'],
            'fuel_level' => $inspectionData['fuel_level_out'],
            'inspection_checklist' => $inspectionData['inspection_checklist'],
            'photos' => $inspectionData['photos'] ?? [],
            'overall_condition' => $inspectionData['overall_condition'],
            'inspection_date' => now(),
            'notes' => $inspectionData['notes'] ?? null,
        ]);

        // Compare with incoming inspection
        $incomingInspection = $jobCard->incomingInspection;
        if ($incomingInspection) {
            $discrepancies = $outgoingInspection->compareWithOtherInspection($incomingInspection);
            
            if (!empty($discrepancies)) {
                // Alert service supervisor about discrepancies
                $this->notificationService->sendQualityAlert($jobCard, $discrepancies);
                
                $outgoingInspection->update([
                    'discrepancies_found' => $discrepancies,
                    'follow_up_required' => true,
                ]);
            } else {
                // No discrepancies, mark as completed
                $jobCard->update([
                    'status' => 'completed',
                    'mileage_out' => $inspectionData['mileage_out'],
                    'fuel_level_out' => $inspectionData['fuel_level_out'],
                    'completion_datetime' => now(),
                ]);

                // Notify customer
                $this->notificationService->notifyVehicleReady($jobCard);
            }
        }
    }

    /**
     * Close job card after delivery
     */
    public function closeJobCard(JobCard $jobCard, array $deliveryData): void
    {
        $jobCard->update([
            'status' => 'delivered',
            'delivery_method' => $deliveryData['delivery_method'],
            'customer_satisfaction_rating' => $deliveryData['satisfaction_rating'] ?? null,
            'completion_datetime' => now(),
        ]);
    }

    /**
     * Get workflow status for a job card
     */
    public function getWorkflowStatus(JobCard $jobCard): array
    {
        return [
            'job_card' => $jobCard,
            'incoming_inspection' => $jobCard->incomingInspection,
            'diagnosis' => $jobCard->diagnosis,
            'estimate' => $jobCard->estimates()->latest()->first(),
            'work_orders' => $jobCard->workOrders,
            'outgoing_inspection' => $jobCard->outgoingInspection,
            'completion_percentage' => $this->calculateCompletionPercentage($jobCard),
        ];
    }

    /**
     * Calculate completion percentage for a job card
     */
    private function calculateCompletionPercentage(JobCard $jobCard): int
    {
        $steps = [
            'received' => 10,
            'in_diagnosis' => 25,
            'estimate_sent' => 40,
            'approved' => 50,
            'in_progress' => 75,
            'quality_check' => 90,
            'completed' => 95,
            'delivered' => 100,
        ];

        return $steps[$jobCard->status] ?? 0;
    }
}
