<?php

namespace App\Livewire\Invoices;

use App\Models\Branch;
use App\Models\Estimate;
use App\Models\Invoice;
use App\Models\Part;
use App\Models\ServiceItem;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Validate;
use Livewire\Component;

class CreateFromEstimate extends Component
{
    public Estimate $estimate;

    #[Validate('required|string|max:255')]
    public $subject = '';

    #[Validate('nullable|string')]
    public $description = '';

    #[Validate('required|exists:branches,id')]
    public $branch_id = '';

    #[Validate('required|date')]
    public $invoice_date = '';

    #[Validate('required|date|after_or_equal:invoice_date')]
    public $due_date = '';

    #[Validate('required|numeric|min:0')]
    public $tax_rate = 0;

    public $lineItems = [];

    public $branches = [];

    public $serviceItems = [];

    public $parts = [];

    public function mount(Estimate $estimate)
    {
        $this->estimate = $estimate;
        $this->authorize('create', Invoice::class);

        // Pre-fill form with estimate data
        $this->subject = $estimate->subject;
        $this->description = $estimate->description;
        $this->branch_id = $estimate->branch_id;
        $this->invoice_date = now()->format('Y-m-d');
        $this->due_date = now()->addDays(30)->format('Y-m-d');
        $this->tax_rate = $estimate->tax_rate;

        // Load estimate line items
        $this->lineItems = $estimate->estimateLineItems->map(function ($item) {
            return [
                'type' => $item->type,
                'service_item_id' => $item->service_item_id,
                'part_id' => $item->part_id,
                'description' => $item->description,
                'quantity' => $item->quantity,
                'unit_price' => $item->unit_price,
                'total' => $item->total,
            ];
        })->toArray();

        $this->loadFormData();
    }

    public function loadFormData()
    {
        $this->branches = Branch::all();
        $this->serviceItems = ServiceItem::all();
        $this->parts = Part::all();
    }

    public function addLineItem()
    {
        $this->lineItems[] = [
            'type' => 'service',
            'service_item_id' => '',
            'part_id' => '',
            'description' => '',
            'quantity' => 1,
            'unit_price' => 0,
            'total' => 0,
        ];
    }

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

    public function updatedLineItems($value, $key)
    {
        $keyParts = explode('.', $key);
        $index = $keyParts[0];
        $field = $keyParts[1];

        if ($field === 'type') {
            // Reset related fields when type changes
            $this->lineItems[$index]['service_item_id'] = '';
            $this->lineItems[$index]['part_id'] = '';
            $this->lineItems[$index]['description'] = '';
            $this->lineItems[$index]['unit_price'] = 0;
        }

        if ($field === 'service_item_id' && $this->lineItems[$index]['type'] === 'service') {
            $serviceItem = ServiceItem::find($value);
            if ($serviceItem) {
                $this->lineItems[$index]['description'] = $serviceItem->name;
                $this->lineItems[$index]['unit_price'] = $serviceItem->price;
            }
        }

        if ($field === 'part_id' && $this->lineItems[$index]['type'] === 'part') {
            $part = Part::find($value);
            if ($part) {
                $this->lineItems[$index]['description'] = $part->name;
                $this->lineItems[$index]['unit_price'] = $part->sell_price;
            }
        }

        // Recalculate total for this line item
        if (in_array($field, ['quantity', 'unit_price'])) {
            $quantity = (float) $this->lineItems[$index]['quantity'];
            $unitPrice = (float) $this->lineItems[$index]['unit_price'];
            $this->lineItems[$index]['total'] = $quantity * $unitPrice;
        }
    }

    public function getSubtotalProperty()
    {
        return collect($this->lineItems)->sum('total');
    }

    public function getTaxAmountProperty()
    {
        return $this->subtotal * ($this->tax_rate / 100);
    }

    public function getTotalProperty()
    {
        return $this->subtotal + $this->taxAmount;
    }

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

        DB::transaction(function () {
            $branch = Branch::find($this->branch_id);
            $invoice = Invoice::create([
                'job_card_id' => $this->estimate->job_card_id,
                'estimate_id' => $this->estimate->id,
                'customer_id' => $this->estimate->customer_id,
                'branch_id' => $this->branch_id,
                'created_by' => auth()->id(),
                'invoice_number' => Invoice::generateInvoiceNumber($branch->code ?? 'MAIN'),
                'subject' => $this->subject,
                'description' => $this->description,
                'invoice_date' => $this->invoice_date,
                'due_date' => $this->due_date,
                'subtotal' => $this->estimate->subtotal_amount,
                'tax_rate' => 10.0, // Default tax rate
                'tax_amount' => $this->estimate->tax_amount,
                'total_amount' => $this->estimate->total_amount,
                'status' => 'draft',
            ]);

            // Copy line items from estimate to invoice
            foreach ($this->estimate->lineItems as $estimateItem) {
                // Map estimate line item types to invoice line item types
                $invoiceType = match ($estimateItem->type) {
                    'parts' => 'part',
                    'labour' => 'labour',
                    'miscellaneous' => 'other',
                    default => $estimateItem->type
                };

                $lineItemData = [
                    'type' => $invoiceType,
                    'description' => $estimateItem->description,
                    'quantity' => $estimateItem->quantity,
                    'unit_price' => $estimateItem->unit_price,
                    'total_amount' => $estimateItem->total_amount,
                ];

                // Add part reference if it's a parts item
                if ($estimateItem->type === 'parts' && $estimateItem->part_id) {
                    $lineItemData['part_id'] = $estimateItem->part_id;
                    $lineItemData['part_number'] = $estimateItem->part->part_number ?? null;
                }

                $invoice->invoiceLineItems()->create($lineItemData);
            }

            $this->invoice = $invoice;
        });

        session()->flash('success', 'Invoice created successfully from estimate.');

        return redirect()->route('invoices.show', $this->invoice);
    }

    public function render()
    {
        return view('livewire.invoices.create-from-estimate')
            ->layout('layouts.app');
    }
}
