<?php

namespace App\Exports;

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

class OrderReportExport implements FromCollection, WithHeadings, WithMapping, ShouldAutoSize, WithStyles, WithEvents
{
    protected $request;
    protected $counter;
    protected $totalAmountSum;
    protected $totaldeliverymanAmount;
    protected $totalAmountorder;
    protected $startDate;
    protected $endDate;

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

    public function collection()
    {
        $userIds = User::where('user_type', 'client')->pluck('id')->toArray();
        $query = Order::whereIn('client_id', $userIds)
                      ->with('payment', 'client', 'city')
                      ->where('status', 'completed');

        if ($this->request->filled('client_id')) {
            $query->where('client_id', $this->request->input('client_id'));
        }

        $fromDate = $this->request->input('from_date');
        $toDate = $this->request->input('to_date');

        if ($fromDate) {
            $query->whereDate('created_at', '>=', $fromDate);
        }

        if ($toDate) {
            $query->whereDate('created_at', '<=', $toDate);
        }

        $orders = $query->get();

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

        $this->totaldeliverymanAmount += $orders->sum(function ($order) {
            return $order->payment->delivery_man_commission ?? 0;
        });

        $this->totalAmountorder = $orders->sum(function ($order) {
            return $order->payment->total_amount ?? 0;
        });

        $data = $orders->map(function ($order) {
            return [
                'id' => $order->id,
                'client_name' => optional($order->client)->name,
                'deliveryman_name' => optional($order->delivery_man)->name,
                'pickup_datetime' => $order->pickup_datetime,
                'delivery_datetime' => $order->delivery_datetime,
                'total_order' => getPriceFormat(optional($order->payment)->total_amount) ?? '-',
                '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' => '',
            'pickup_datetime' => '',
            'delivery_datetime' => '',
            'total_order' => getPriceFormat($this->totalAmountorder) ?? '-',
            '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['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['total_order'] ?? '-',
            $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');
            $date = ($fromDate && $toDate) ? 'From Date: ' . ($fromDate ?: '-') . ' To Date ' . ($toDate ?: '-') : null;
    
            $headings = [
                [
                   __('message.admin_earning_report') . ($date ? ' : ' . $date : ''),
                ],
                [''],
                [
                    __('message.id'),
                    __('message.order_id'),
                    __('message.user'),
                    __('message.delivery_man_excel'),
                    __('message.pickup_date_time_excel'),
                    __('message.delivery_date_time_excel'),
                    __('message.total_amount_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.pickup_date_time_pdf'),
                __('message.delivery_date_time_pdf'),
                __('message.total_amount_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 getTotalAmountSum()
    {
        return getPriceFormat($this->totalAmountSum);
    }
    public function getTotaldeliverymanAmount()
    {
        return $this->totaldeliverymanAmount;
    }

    public function getTotalAmountorder()
    {
        return getPriceFormat($this->totalAmountorder);
    }
}