<?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 {
            // Load the estimate with relationships for PDF generation
            $estimate = $this->estimate->load([
                'customer',
                'jobCard.customer',
                'jobCard.vehicle',
                'vehicle',
                'lineItems.part',
                'preparedBy',
                'diagnosis',
            ]);

            // For now, let's use a simple approach that should work
            // First, verify HTML generation works
            $html = view('estimates.pdf', compact('estimate'))->render();

            if (empty($html)) {
                throw new \Exception('Failed to generate HTML template');
            }

            // Try different approaches for PDF generation
            try {
                // Approach 1: Use Laravel's PDF facade if available
                if (class_exists('\Barryvdh\DomPDF\Facade\Pdf')) {
                    $pdf = \Barryvdh\DomPDF\Facade\Pdf::loadHtml($html);
                    $pdf->setPaper('letter', 'portrait');
                    $output = $pdf->output();
                } else {
                    throw new \Exception('PDF facade not available');
                }
            } catch (\Exception $e1) {
                try {
                    // Approach 2: Direct DomPDF instantiation
                    $dompdf = new \Dompdf\Dompdf;
                    $dompdf->loadHtml($html);
                    $dompdf->setPaper('letter', 'portrait');
                    $dompdf->render();
                    $output = $dompdf->output();
                } catch (\Exception $e2) {
                    // Approach 3: Return HTML for now
                    $filename = 'estimate-'.$estimate->estimate_number.'.html';

                    return response()->streamDownload(function () use ($html) {
                        echo $html;
                    }, $filename, [
                        'Content-Type' => 'text/html',
                        'Content-Disposition' => 'attachment; filename="'.$filename.'"',
                    ]);
                }
            }

            // Create filename with estimate number
            $filename = 'estimate-'.$estimate->estimate_number.'.pdf';

            // Return PDF for download
            return response()->streamDownload(function () use ($output) {
                echo $output;
            }, $filename, [
                'Content-Type' => 'application/pdf',
                'Content-Disposition' => 'attachment; filename="'.$filename.'"',
            ]);

        } catch (\Exception $e) {
            // Log the error for debugging
            Log::error('PDF generation failed for estimate '.$this->estimate->id, [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            // Show user-friendly error message
            session()->flash('error', 'Failed to generate PDF: '.$e->getMessage());

            return null;
        }
    }

    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]);
    }

    public function convertToInvoice()
    {
        if ($this->estimate->customer_approval_status !== 'approved') {
            session()->flash('error', 'Estimate must be approved before converting to invoice.');

            return;
        }

        if (! auth()->user()->can('create', \App\Models\Invoice::class)) {
            session()->flash('error', 'You do not have permission to create invoices.');

            return;
        }

        return redirect()->route('invoices.create-from-estimate', $this->estimate);
    }

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