<?php
namespace App\Http\Controllers;

use App\Models\Job;
use App\Models\AppSetting;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;

class GrossProfitDetailController extends Controller
{
    public function show(Job $job)
    {
        $data = $this->buildData($job);
        return view('gross-profit.show', $data);
    }

    public function pdf(Job $job)
    {
        $data = $this->buildData($job);
        $pdf  = Pdf::loadView('gross-profit.pdf', $data)->setPaper('a4', 'portrait');
        return $pdf->download('gross-profit-' . $job->job_number . '.pdf');
    }

    private function buildData(Job $job): array
    {
        $directRoles = ['processor', 'factory_employee', 'lead_installer'];

        $job->load([
            'contact', 'manager', 'consultant',
            'quotes.sections.items',
            'poAllocations.purchaseOrder',
            'poAllocations.stock',
            'variants',
            'jobInvoices.creator',
            'worksOrders.faults',
        ]);

        // Labour: direct roles always counted; others need approved/paid invoice
        $job->load(['timeEntries' => fn($q) => $q->where('status', 'completed')
            ->with(['user.role', 'invoice'])]);

        // Revenue from latest accepted/converted quote
        $quote = $job->quotes()->whereIn('status', ['accepted','converted'])->latest()->first()
            ?? $job->quotes()->latest()->first();

        $allItems     = $quote ? $quote->sections->flatMap->items : collect();
        $quoteRevenue = $allItems->sum(fn($i) => (float)($i->total_retail ?? $i->total ?? 0));
        $matCost      = $allItems->sum(fn($i) => (float)($i->total_wsale ?? 0));

        // Accepted variants
        $acceptedVariants = $job->variants->where('status', 'accepted');
        $variantRevenue   = (float) $acceptedVariants->sum('price_adjustment');

        // Job invoice deductions (reduce gross profit, not revenue)
        $invoiceLines = $job->jobInvoices->map(fn($inv) => [
            'invoice_number' => $inv->invoice_number ?? '—',
            'invoice_date'   => $inv->invoice_date?->format('d M Y') ?? '—',
            'amount'         => (float)($inv->invoice_amount ?? 0),
            'note'           => $inv->note ?? '',
            'added_by'       => $inv->creator?->name ?? '—',
        ]);
        $invoiceDeductions = $invoiceLines->sum('amount');

        $revenue = $quoteRevenue + $variantRevenue;

        // Labour: direct roles always count; trades/others need approved invoice
        $labourLines = $job->timeEntries->filter(function ($entry) use ($directRoles) {
            $role = $entry->user?->role?->name ?? '';
            if (in_array($role, $directRoles)) return true;
            return $entry->invoice && in_array($entry->invoice->status, ['approved', 'paid']);
        })->map(function ($entry) {
            $hours = round(($entry->duration_minutes ?? 0) / 60, 2);
            $rate  = (float)($entry->user?->hourly_rate ?? 0);
            return [
                'staff' => $entry->user?->name ?? 'Unknown',
                'role'  => $entry->user?->role?->name ?? '',
                'hours' => $hours,
                'rate'  => $rate,
                'cost'  => round($hours * $rate, 2),
                'date'  => optional($entry->started_at ?? $entry->created_at)->format('d M Y'),
            ];
        })->filter(fn($r) => $r['cost'] > 0);

        $labourCost = $labourLines->sum('cost');

        // PO allocations
        $poLines = $job->poAllocations->map(fn($a) => [
            'description' => $a->description,
            'source'      => $a->purchaseOrder?->po_number ?? ($a->stock ? 'Stock: ' . $a->stock->sku : '—'),
            'qty'         => (float)$a->qty,
            'unit_cost'   => (float)$a->unit_cost,
            'total'       => (float)$a->total_cost,
        ]);
        $poCost = $poLines->sum('total');

        // Works order fault deductions
        $faultLines = $job->worksOrders->flatMap(function ($wo) {
            return $wo->faults->map(fn($f) => [
                'wo_number'  => $wo->order_number,
                'fault_num'  => $f->fault_number,
                'fault_type' => $f->fault_type ?? '—',
                'cost'       => (float) $f->cost,
                'approved'   => $wo->fault_approval_status,
            ]);
        })->filter(fn($f) => $f['cost'] > 0);
        $faultDeductions = $faultLines->sum('cost');

        $totalCost   = $matCost + $labourCost + $poCost;
        $grossProfit = $revenue - $totalCost - $invoiceDeductions - $faultDeductions;
        $margin      = $revenue > 0 ? round(($grossProfit / $revenue) * 100, 1) : 0;

        return compact(
            'job', 'quote', 'allItems', 'revenue', 'quoteRevenue', 'matCost',
            'acceptedVariants', 'variantRevenue',
            'invoiceLines', 'invoiceDeductions',
            'labourLines', 'labourCost', 'poLines', 'poCost',
            'faultLines', 'faultDeductions',
            'totalCost', 'grossProfit', 'margin'
        );
    }
}