<?php

namespace App\Domains\Virtual\Exports;

use App\Dicts;
use Carbon\Carbon;
use App\Core\AbstractExport;
use Illuminate\Support\Facades\DB;
use Dipper\Excel\Concerns\WithRows;
use Dipper\Excel\Concerns\FromQuery;
use Dipper\Excel\Concerns\WithHeadings;
use App\Domains\Virtual\Services\CommonService;
use Dipper\Excel\Concerns\WithColumnFormatting;
use App\Domains\Virtual\Services\CompanyService;
use App\Domains\Virtual\Services\PackageService;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use App\Domains\Virtual\Repositories\OrderRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;

class OrderExport extends AbstractExport implements FromQuery, WithHeadings, WithRows, WithColumnFormatting
{
    public $conditions;

    public function __construct(array $conditions = [])
    {
        if (isset($conditions['sim'])) {
            $conditions['sim'] = array_map('intval', array_map('trim', str_to_array($conditions['sim'], "\n")));
        }

        $this->conditions = $conditions;
        parent::__construct();
    }

    public function query()
    {
        $builder = app(OrderRepository::class)->forceNoReset()->withConditions($this->conditions)->applyConditions()
            ->orderBy('order_at', 'desc');

        return $builder;
    }

    public function headings(): array
    {
        $headings = [
            '订单编号',
            '企业名称',
            '运营商',
            '套餐名称',
            '套餐单价',
            '支付方式',
            '支付流水号',
            '订单量',
            '订单金额',
            '订单时间',
        ];

        if ($this->conditions['type'] == 0) {
            array_splice($headings, 8, 0, [
                '发货量',
                '退货量',
                '订单状态',
                // '收款状态',
            ]);
        }


        return $headings;
    }

    /**
     * @param mixed $row
     *
     * @return mixed
     */
    public function rows($rows)
    {
        $array = [];

        $orderShipments = app(OrderCardPartitionRepository::class)->select([
            'order_id',
            DB::raw('SUM(counts) as counts'),
            DB::raw('SUM(CASE WHEN refunded_at IS NULL THEN 0 ELSE 1 END) as refunds')
        ])->withConditions([
            'order_id' => array_pluck($rows, 'id'),
        ])->groupBy('order_id')->get()->keyBy('order_id')->toArray();

        $dicts = app(Dicts::class);
        $carrierOperators = $dicts->get('carrier_operator');
        $orderStatues = $dicts->get('order_status');
        $transactionStatuses = $dicts->get('transaction_status');

        foreach ($rows as $item) {
            $carrier_operator = PackageService::load($item['package_id'])['carrier_operator'];

            $data = [
                "{$item['sn']}\t",
                CompanyService::load($item['company_id'])['name'] ?? '',
                $carrierOperators[$carrier_operator],
                PackageService::load($item['package_id'])['name'] ?? '',
                sprintf('%.02f', $item['unit_price']/100),
                CommonService::namePayChannel($item['pay_channel']),
                "{$item['transaction_no']}\t",
                $item['counts'],
                sprintf('%.02f', $item['unit_price']*$item['counts']/100),
                Carbon::parse($item['order_at'])->format('Y-m-d'),
            ];

            if ($this->conditions['type'] == 0) {
                array_splice($data, 8, 0, [
                    sprintf('%d', $orderShipments[$item['id']]['counts'] ?? 0),
                    sprintf('%d', $orderShipments[$item['id']]['refunds'] ?? 0),
                    $orderStatues[$item['order_status']],
                    // $transactionStatuses[$item['order']['transaction_status']],
                ]);
            }

            $array[] =  $data;
        }

        return $array;
    }

    /**
     * @return array
     */
    public function columnFormats(): array
    {
        return [
            'E' => NumberFormat::FORMAT_NUMBER_00,
            'H' => NumberFormat::FORMAT_NUMBER,
            'I' => NumberFormat::FORMAT_NUMBER,
            'J' => NumberFormat::FORMAT_NUMBER,
            'L' => NumberFormat::FORMAT_NUMBER_00,
        ];
    }
}
