<?php

namespace App\Exports;

use App\Models\Order;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Carbon\Carbon;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Maatwebsite\Excel\Concerns\WithStyles;


class ReportOfUserExport implements FromCollection,WithHeadings, WithMapping, ShouldAutoSize, WithEvents, WithStyles
{
    /**
    * @return \Illuminate\Support\Collection
    */
    protected $request;
    protected $counter;
    protected $orders;
    protected $totalAmountorder;
    protected $totalAmountSum;
    protected $totaldeliverymanAmount;
    protected $startDate;
    protected $endDate;
    protected $deliveryname;

    public function __construct(Request $request)
    {
        $this->request = $request;
        $this->counter = 1;
        $this->orders = $request['orders'];
        $this->totalAmountSum = 0;
        $this->totaldeliverymanAmount = 0;
        $this->totalAmountorder = 0;
        $this->startDate;
        $this->endDate;
        $this->deliveryname;
       
    }

    public function collection()
    {
        $params = [
            'from_date' => $this->request->input('from_date'),
            'to_date' => $this->request->input('to_date'),
            'client_id' => $this->request->input('client_id'),
        ];

        $ordersQuery = Order::query()->with('client')->where('status', 'completed');

        if ($this->request->filled('client_id')) {
            $ordersQuery->where('client_id', $params['client_id']);
        }

        if ($params['from_date']) {
            $ordersQuery->whereDate('created_at', '>=', $params['from_date']);
        }

        if ($params['to_date']) {
            $ordersQuery->whereDate('created_at', '<=', $params['to_date']);
        }

        $orders = $ordersQuery->get();
        $this->totalAmountorder = $orders->sum(function ($order) {
            return $order->payment->total_amount ?? '-';
        });
        $this->totaldeliverymanAmount += $orders->sum(function ($order) {
            return $order->payment->delivery_man_commission ?? '-';
        });

        $this->totalAmountSum = $orders->sum(function ($order) {
            return $order->payment->admin_commission ?? '-';
        });

        $data = $orders->map(function ($order) {
            return [
                'id' => $order->id,
                'client_name' => optional($order->client)->name,
                'deliveryman_name' => optional($order->delivery_man)->name,
                'total_order' => getPriceFormat(optional($order->payment)->total_amount),
                'pickup_datetime' => $order->pickup_datetime,
                'delivery_datetime' => $order->delivery_datetime,
                'commission_type' => optional($order->city)->commission_type,
                'admin_commission' => getPriceFormat(optional($order->payment)->admin_commission),
                'deliveryman_commission' => getPriceFormat(optional($order->payment)->delivery_man_commission),
            ];
        })->toArray();


        $data[] = [
            'id' => '',
            'client_name' => 'Total',
            'deliveryman_name' => '',
            'total_order' => getPriceFormat($this->totalAmountorder) ?? '-',
            'pickup_datetime' => '',
            'delivery_datetime' => '',
            'commission_type' => '-',
            'admin_commission' => getPriceFormat($this->totalAmountSum) ?? '-',
            'deliveryman_commission' => getPriceFormat($this->totaldeliverymanAmount) ?? '-',
        ];

        return collect($data);
    }


    public function map($order): array
    {
        if ($order['client_name'] === 'Total') {
            return [
                '',
                '',
                'Total',
                '',
                $order['total_order'],
                '',
                '',
                '',
                $order['admin_commission'],
                $order['deliveryman_commission'],
            ];
        }

        return [
            $this->counter++,
            $order['id'] ?? '-',
            $order['client_name'] ?? '-',
            $order['deliveryman_name'] ?? '-',
            $order['total_order'] ?? '-',
            $order['pickup_datetime'] ? \Carbon\Carbon::parse($order['pickup_datetime'])->format('d-m-Y H:i:s') : '-',
            $order['delivery_datetime'] ? \Carbon\Carbon::parse($order['delivery_datetime'])->format('d-m-Y H:i:s') : '-',
            $order['commission_type'] ?? '-',
            $order['admin_commission'] ?? '-',
            $order['deliveryman_commission'] ?? '-',
        ];
    }


    public function headings($exportType = 'excel'): array
    {
        if ($exportType === 'excel') {
            $fromDate = $this->request->input('from_date');
            $toDate = $this->request->input('to_date');
            $clientId = $this->request->input('client_id');
        
            $date = ($fromDate && $toDate) ? 'From Date: ' . ($fromDate ?: '-') . ' To Date: ' . ($toDate ?: '-') : null;
        
            $clientName = User::where('user_type', 'client')->where('id', $clientId)->first();
            $clientnameget = $clientName ? $clientName->name : '-';
        
            $headings = [
                [
                    __('message.report_of')  . $clientnameget . ' ' . ($date ? ' : ' . $date : ''),
                ],
                [''],
                [
                    __('message.id'),
                    __('message.order_id'),
                    __('message.user'),
                    __('message.delivery_man_excel'),
                    __('message.total_amount_excel'),
                    __('message.pickup_date_time_excel'),
                    __('message.delivery_date_time_excel'),
                    __('message.commission_type_excel'),
                    __('message.admin_commission_excel'),
                    __('message.delivery_man_commission_excel'),
                ],
            ];
        }else {
                $headings = [
                    __('message.id'),
                    __('message.order_id'),
                    __('message.user'),
                    __('message.delivery_man_pdf'),
                    __('message.total_amount_pdf'),
                    __('message.pickup_date_time_pdf'),
                    __('message.delivery_date_time_pdf'),
                    __('message.commission_type_pdf'),
                    __('message.admin_commission_pdf'),
                    __('message.delivery_man_commission_pdf'),
                ];
            }
        
            return $headings;
    }
    public function styles(Worksheet $sheet)
    {
        $highestRow = $sheet->getHighestRow();
        $highestColumn = $sheet->getHighestColumn();

        $sheet->mergeCells('A1:' . $highestColumn . '1');
        $sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);

        for ($row = 1; $row <= $highestRow; $row++) {

            $cellValueI = $sheet->getCell('H' . $row)->getValue();
            if ($cellValueI) {
                $sheet->getCell('H' . $row)->setValue(ucfirst(strtolower($cellValueI)));
            }
            if ($row === 1 || $sheet->getCell('C' . $row)->getValue() === 'Total') {
                $sheet->getStyle('A' . $row . ':' . $highestColumn . $row)->applyFromArray([
                    'font' => [
                        'bold' => true,
                    ],
                    'alignment' => [
                        'horizontal' => Alignment::HORIZONTAL_CENTER,
                        'vertical' => Alignment::VERTICAL_CENTER,
                    ],
                ]);
            }
        }
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function(AfterSheet $event) {
                $event->sheet->getDelegate()->getStyle('A:J')
                    ->getAlignment()
                    ->setHorizontal(Alignment::HORIZONTAL_CENTER);
            },
        ];
    }

    public function getTotalAmountSumorder()
    {
        return $this->totalAmountorder;
    }
    public function getTotalAmountSum()
    {
        return $this->totalAmountSum;
    }
    public function getTotaldeliverymanAmount()
    {
        return $this->totaldeliverymanAmount;
    }
}
