<?php

namespace App\Classes\Modules\Exports\Services;

use App\Models\Order;
use App\Models\PackingList;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;

class ExportsArrivedParcel implements WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize, FromQuery
{
    use Exportable;

    private $start_date;
    private $end_date;

    public function __construct($start_date = null, $end_date = null)
    {
        $this->start_date = $start_date;
        $this->end_date = $end_date;
    }

    public function headings(): array
    {
        return [
            'ORDER NUMBER',
            'Marking',
            'Warehouse',
            'Cbm',
            'Description',
            'Quantity',
            'Received Date',
            'Recorded On',
            'Days to Record',
            'Remarks'
        ];
    }

    public function query()
    {
        $query = PackingList::with([
            'owner.companyModule.inviters',
            'owner.orderRoles',
            'packages',
            'transports'
        ])
            ->where('type', '=', 1)
            ->where('status', '=', 2)
            ->where('owner_type', Order::class);

        if (!is_null($this->start_date) && !is_null($this->end_date)) {
            $query->whereHas('transports', function ($q) {
                $q->whereBetween('drop_date', [
                    Carbon::parse($this->start_date)->startOfDay(),
                    Carbon::parse($this->end_date)->endOfDay()
                ]);
            });
        }

        return $query;
    }

    public function map($packingList): array
    {
        $order = $packingList->owner;
        $marking = $order->companyModule->getMarking();
        $warehouse = $order->orderRoles->firstWhere('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->appointee;
        $cbm = $packingList->packages->sum(function ($package) {
            return (($package->width / 100) * ($package->height / 100) * ($package->length / 100)) * $package->quantity;
        });
        $arrival_date = $packingList->transports->first()->drop_date->format('d-m-Y');
        $recorded_on = $packingList->created_at->format('d-m-Y');
        $days_to_record = Carbon::parse($arrival_date)->diffInDays(Carbon::parse($recorded_on));

        return [
            $packingList->owner->reference,
            $marking,
            $warehouse->reference,
            $cbm,
            $packingList->packages->implode('description', ', '),
            $packingList->packages->sum('quantity'),
            $arrival_date,
            $recorded_on,
            $days_to_record,
            ''
        ];
    }
}
