<?php

namespace App\Livewire\Estimates;

use App\Models\Customer;
use App\Models\Estimate;
use App\Models\EstimateLineItem;
use App\Models\Part;
use App\Models\Vehicle;
use Livewire\Attributes\Layout;
use Livewire\Component;

class CreateStandalone extends Component
{
    public $customerId = '';

    public $vehicleId = '';

    public $selectedCustomer = null;

    public $selectedVehicle = null;

    public $customerVehicles = [];

    public $terms_and_conditions = '';

    public $validity_period_days = 30;

    public $tax_rate = 8.25;

    public $discount_amount = 0;

    public $notes = '';

    public $internal_notes = '';

    public $lineItems = [];

    public $subtotal = 0;

    public $tax_amount = 0;

    public $total_amount = 0;

    // Parts search
    public $partSearch = '';

    public $availableParts = [];

    public $showPartsDropdown = false;

    protected $rules = [
        'customerId' => 'required|exists:customers,id',
        'vehicleId' => 'required|exists:vehicles,id',
        'terms_and_conditions' => 'required|string',
        'validity_period_days' => 'required|integer|min:1|max:365',
        'tax_rate' => 'required|numeric|min:0|max:50',
        'discount_amount' => 'nullable|numeric|min:0',
        'lineItems.*.type' => 'required|in:labor,parts,miscellaneous',
        'lineItems.*.description' => 'required|string',
        'lineItems.*.quantity' => 'required|numeric|min:0.01',
        'lineItems.*.unit_price' => 'required|numeric|min:0',
        'lineItems.*.part_id' => 'nullable|exists:parts,id',
    ];

    public function mount()
    {
        $this->initializeDefaults();
        $this->addLineItem();
    }

    private function initializeDefaults()
    {
        $this->terms_and_conditions = 'This estimate is valid for '.$this->validity_period_days.' days from the date of issue. All prices are subject to change without notice. Additional charges may apply for unforeseen complications.';
    }

    public function updatedCustomerId($value)
    {
        if ($value) {
            $this->selectedCustomer = Customer::find($value);
            $this->customerVehicles = Vehicle::where('customer_id', $value)->get();
            $this->vehicleId = '';
            $this->selectedVehicle = null;
        } else {
            $this->selectedCustomer = null;
            $this->customerVehicles = [];
            $this->vehicleId = '';
            $this->selectedVehicle = null;
        }
    }

    public function updatedVehicleId($value)
    {
        if ($value) {
            $this->selectedVehicle = Vehicle::find($value);
        } else {
            $this->selectedVehicle = null;
        }
    }

    public function addLineItem()
    {
        $this->lineItems[] = [
            'part_id' => null,
            'part_number' => '',
            'description' => '',
            'quantity' => 1,
            'unit_price' => 0,
            'subtotal' => 0,
            'type' => 'labour',
            'stock_available' => null,
        ];
    }

    public function removeLineItem($index)
    {
        unset($this->lineItems[$index]);
        $this->lineItems = array_values($this->lineItems);
        $this->calculateTotals();
    }

    public function updatedLineItems($value, $name)
    {
        // Extract the index and field name from the wire:model path
        if (preg_match('/(\d+)\.(.+)/', $name, $matches)) {
            $index = $matches[1];
            $field = $matches[2];

            // Validate stock levels for parts
            if ($field === 'quantity' && isset($this->lineItems[$index]['part_id']) && $this->lineItems[$index]['part_id']) {
                $part = Part::find($this->lineItems[$index]['part_id']);
                if ($part && $value > $part->quantity_on_hand) {
                    $this->addError("lineItems.{$index}.quantity", "Quantity cannot exceed available stock ({$part->quantity_on_hand})");

                    return;
                }
            }

            // Clear the quantity error if validation passes
            if ($field === 'quantity') {
                $this->resetErrorBag("lineItems.{$index}.quantity");
            }
        }

        $this->calculateTotals();
    }

    public function updatedPartSearch()
    {
        $this->searchParts($this->partSearch);
    }

    public function calculateTotals()
    {
        $this->subtotal = 0;

        foreach ($this->lineItems as $index => $item) {
            if (isset($item['quantity'], $item['unit_price'])) {
                $lineSubtotal = $item['quantity'] * $item['unit_price'];
                $this->lineItems[$index]['subtotal'] = $lineSubtotal;
                $this->subtotal += $lineSubtotal;
            }
        }

        $discountedSubtotal = max(0, $this->subtotal - ($this->discount_amount ?? 0));
        $this->tax_amount = $discountedSubtotal * ($this->tax_rate / 100);
        $this->total_amount = $discountedSubtotal + $this->tax_amount;
    }

    public function searchParts($query = '')
    {
        if (strlen($query) < 2) {
            $this->availableParts = [];
            $this->showPartsDropdown = false;

            return;
        }

        $this->availableParts = Part::where('status', 'active')
            ->where(function ($q) use ($query) {
                $q->where('name', 'like', "%{$query}%")
                    ->orWhere('part_number', 'like', "%{$query}%")
                    ->orWhere('description', 'like', "%{$query}%");
            })
            ->orderBy('name')
            ->limit(10)
            ->get();

        $this->showPartsDropdown = true;
    }

    public function selectPart($lineIndex, $partId)
    {
        $part = Part::find($partId);

        if ($part) {
            $this->lineItems[$lineIndex]['part_id'] = $part->id;
            $this->lineItems[$lineIndex]['part_number'] = $part->part_number;
            $this->lineItems[$lineIndex]['description'] = $part->name;
            $this->lineItems[$lineIndex]['unit_price'] = $part->sell_price;
            $this->lineItems[$lineIndex]['stock_available'] = $part->quantity_on_hand;
            $this->lineItems[$lineIndex]['type'] = 'parts';

            $this->calculateTotals();
        }

        $this->partSearch = '';
        $this->availableParts = [];
        $this->showPartsDropdown = false;
    }

    public function clearPartSelection($lineIndex)
    {
        $this->lineItems[$lineIndex]['part_id'] = null;
        $this->lineItems[$lineIndex]['part_number'] = '';
        $this->lineItems[$lineIndex]['stock_available'] = null;
        $this->calculateTotals();
    }

    public function save()
    {
        $this->validate();

        if (empty($this->lineItems)) {
            session()->flash('error', 'At least one line item is required.');

            return;
        }

        $estimate = Estimate::create([
            'estimate_number' => $this->generateEstimateNumber(),
            'customer_id' => $this->customerId,
            'vehicle_id' => $this->vehicleId,
            'job_card_id' => null, // No job card for standalone estimates
            'diagnosis_id' => null, // No diagnosis for standalone estimates
            'status' => 'draft',
            'customer_approval_status' => 'pending',
            'terms_and_conditions' => $this->terms_and_conditions,
            'validity_period_days' => $this->validity_period_days,
            'tax_rate' => $this->tax_rate,
            'discount_amount' => $this->discount_amount ?? 0,
            'subtotal_amount' => $this->subtotal,
            'tax_amount' => $this->tax_amount,
            'total_amount' => $this->total_amount,
            'notes' => $this->notes,
            'internal_notes' => $this->internal_notes,
            'prepared_by_id' => auth()->id(),
        ]);

        foreach ($this->lineItems as $item) {
            EstimateLineItem::create([
                'estimate_id' => $estimate->id,
                'part_id' => $item['part_id'],
                'part_number' => $item['part_number'],
                'type' => $item['type'],
                'description' => $item['description'],
                'quantity' => $item['quantity'],
                'unit_price' => $item['unit_price'],
                'total_amount' => $item['quantity'] * $item['unit_price'], // Calculate total_amount
                'subtotal' => $item['subtotal'],
            ]);
        }

        session()->flash('success', 'Estimate created successfully.');

        return redirect()->route('estimates.show', $estimate);
    }

    private function generateEstimateNumber()
    {
        $lastEstimate = Estimate::latest()->first();
        $lastNumber = $lastEstimate ? (int) substr($lastEstimate->estimate_number, -5) : 0;

        return 'EST-'.str_pad($lastNumber + 1, 5, '0', STR_PAD_LEFT);
    }

    #[Layout('components.layouts.app')]
    public function render()
    {
        $customers = Customer::orderBy('first_name')->orderBy('last_name')->get();

        return view('livewire.estimates.create-standalone', [
            'customers' => $customers,
        ]);
    }
}
