<?php

namespace App\Livewire\Estimates;

use App\Models\Estimate;
use App\Notifications\EstimateNotification;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Log;
use Livewire\Attributes\Layout;
use Livewire\Component;

class Show extends Component
{
    public Estimate $estimate;

    public $showItemDetails = false;

    public function mount(Estimate $estimate)
    {
        $this->estimate = $estimate->load([
            'jobCard.customer',
            'jobCard.vehicle',
            'jobCard.branch',
            'customer', // For standalone estimates
            'vehicle',  // For standalone estimates
            'diagnosis',
            'preparedBy',
            'lineItems',
            'workOrders',
        ]);
    }

    public function approveEstimate()
    {
        if (! auth()->user()->can('approve', $this->estimate)) {
            session()->flash('error', 'You do not have permission to approve this estimate.');

            return;
        }

        try {
            $this->estimate->update([
                'customer_approval_status' => 'approved',
                'customer_approved_at' => now(),
                'customer_approval_method' => 'staff_portal',
                'status' => 'approved',
            ]);

            // Update job card status to approved (if job card exists)
            if ($this->estimate->jobCard) {
                $this->estimate->jobCard->update([
                    'status' => 'approved',
                ]);
            }

            // Notify relevant parties
            $customer = $this->estimate->customer ?? $this->estimate->jobCard?->customer;
            if ($customer) {
                $customer->notify(
                    new EstimateNotification($this->estimate, 'approved')
                );
            }

            Log::info('Estimate approved', [
                'estimate_id' => $this->estimate->id,
                'approved_by' => auth()->id(),
            ]);

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

            // Refresh estimate data
            $this->estimate->refresh();
            $this->dispatch('$refresh');

        } catch (\Exception $e) {
            Log::error('Failed to approve estimate', [
                'estimate_id' => $this->estimate->id,
                'error' => $e->getMessage(),
            ]);

            session()->flash('error', 'Failed to approve estimate. Please try again.');
        }
    }

    public function rejectEstimate()
    {
        if (! auth()->user()->can('reject', $this->estimate)) {
            session()->flash('error', 'You do not have permission to reject this estimate.');

            return;
        }

        try {
            $this->estimate->update([
                'customer_approval_status' => 'rejected',
                'customer_approved_at' => now(),
                'customer_approval_method' => 'staff_portal',
                'status' => 'rejected',
            ]);

            // Notify relevant parties
            $customer = $this->estimate->customer ?? $this->estimate->jobCard?->customer;
            if ($customer) {
                $customer->notify(
                    new EstimateNotification($this->estimate, 'rejected')
                );
            }

            Log::info('Estimate rejected', [
                'estimate_id' => $this->estimate->id,
                'rejected_by' => auth()->id(),
            ]);

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

            // Refresh estimate data
            $this->estimate->refresh();
            $this->dispatch('$refresh');

        } catch (\Exception $e) {
            Log::error('Failed to reject estimate', [
                'estimate_id' => $this->estimate->id,
                'error' => $e->getMessage(),
            ]);

            session()->flash('error', 'Failed to reject estimate. Please try again.');
        }
    }

    public function sendToCustomer()
    {
        try {
            $this->estimate->update([
                'status' => 'sent',
                'sent_to_customer_at' => now(),
                'sent_by_id' => auth()->id(),
            ]);

            // Send notification to customer
            $customer = $this->estimate->customer ?? $this->estimate->jobCard?->customer;
            if ($customer) {
                $customer->notify(
                    new EstimateNotification($this->estimate, 'sent')
                );
            }

            // Update job card status (if job card exists)
            if ($this->estimate->jobCard) {
                $this->estimate->jobCard->update([
                    'status' => 'estimate_sent',
                ]);
            }

            Log::info('Estimate sent to customer', [
                'estimate_id' => $this->estimate->id,
                'customer_id' => $this->estimate->customer_id ?? $this->estimate->jobCard?->customer?->id,
                'sent_by' => auth()->id(),
            ]);

            session()->flash('success', 'Estimate sent to customer successfully.');

            // Refresh estimate data
            $this->estimate->refresh();
            $this->dispatch('$refresh');

        } catch (\Exception $e) {
            Log::error('Failed to send estimate to customer', [
                'estimate_id' => $this->estimate->id,
                'error' => $e->getMessage(),
            ]);

            session()->flash('error', 'Failed to send estimate to customer. Please try again.');
        }
    }

    public function duplicateEstimate()
    {
        try {
            // Create a new estimate based on current one
            $newEstimate = $this->estimate->replicate();
            $newEstimate->estimate_number = 'EST-'.str_pad(Estimate::max('id') + 1, 6, '0', STR_PAD_LEFT);
            $newEstimate->status = 'draft';
            $newEstimate->customer_approval_status = 'pending';
            $newEstimate->sent_to_customer_at = null;
            $newEstimate->customer_viewed_at = null;
            $newEstimate->customer_approved_at = null;
            $newEstimate->prepared_by_id = auth()->id();
            $newEstimate->save();

            // Duplicate line items
            foreach ($this->estimate->lineItems as $lineItem) {
                $newLineItem = $lineItem->replicate();
                $newLineItem->estimate_id = $newEstimate->id;
                $newLineItem->save();
            }

            Log::info('Estimate duplicated', [
                'original_estimate_id' => $this->estimate->id,
                'new_estimate_id' => $newEstimate->id,
                'duplicated_by' => auth()->id(),
            ]);

            session()->flash('success', 'Estimate has been duplicated successfully.');

            return redirect()->route('estimates.edit', $newEstimate);

        } catch (\Exception $e) {
            Log::error('Failed to duplicate estimate', [
                'estimate_id' => $this->estimate->id,
                'error' => $e->getMessage(),
            ]);

            session()->flash('error', 'Failed to duplicate estimate. Please try again.');
        }
    }

    public function downloadPDF()
    {
        try {
            // Generate PDF using DomPDF
            $pdf = Pdf::loadView('estimates.pdf', [
                'estimate' => $this->estimate,
            ]);

            // Log the download
            Log::info('Estimate PDF downloaded', [
                'estimate_id' => $this->estimate->id,
                'downloaded_by' => auth()->id(),
            ]);

            return response()->streamDownload(function () use ($pdf) {
                echo $pdf->output();
            }, "estimate-{$this->estimate->estimate_number}.pdf");

        } catch (\Exception $e) {
            Log::error('Failed to generate estimate PDF', [
                'estimate_id' => $this->estimate->id,
                'error' => $e->getMessage(),
            ]);

            session()->flash('error', 'Failed to generate PDF. Please try again.');
        }
    }

    public function toggleItemDetails()
    {
        $this->showItemDetails = ! $this->showItemDetails;
    }

    public function refreshEstimate()
    {
        $this->estimate->refresh();
        session()->flash('success', 'Estimate data refreshed.');
        $this->dispatch('$refresh');
    }

    public function createWorkOrder()
    {
        if ($this->estimate->customer_approval_status !== 'approved') {
            session()->flash('error', 'Estimate must be approved before creating a work order.');

            return;
        }

        return redirect()->route('work-orders.create', ['estimate' => $this->estimate->id]);
    }

    #[Layout('components.layouts.app')]
    public function render()
    {
        return view('livewire.estimates.show');
    }
}
