<?php

namespace App\Domains\Virtual\Exports;

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 Illuminate\Database\Eloquent\Collection;
use App\Domains\Virtual\Services\CardService;
use Dipper\Excel\Concerns\WithCustomChunkSize;
use Dipper\Excel\Concerns\WithCustomQuerySize;
use Dipper\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use App\Domains\Virtual\Repositories\PropertyRepository;
use App\Domains\Virtual\Repositories\OrderCardRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;

class CardExport extends AbstractExport implements FromQuery, WithHeadings, WithRows, WithColumnFormatting, WithCustomQuerySize, WithCustomChunkSize
{
    /**
     * @return int
     */
    public function chunkSize(): int
    {
        return 30000;
    }


    public $conditions;

    public function __construct(array $conditions = [])
    {
        $this->conditions = $conditions;
        parent::__construct();
    }

    /**
     * Queued exportables are processed in chunks; each chunk being a job pushed to the queue by the QueuedWriter.
     * In case of exportables that implement the FromQuery concern, the number of jobs is calculated by dividing the $query->count() by the chunk size.
     * Depending on the implementation of the query() method (eg. When using a groupBy clause), this calculation might not be correct.
     *
     * When this is the case, you should use this method to provide a custom calculation of the query size.
     *
     * @return int
     */
    public function querySize(): int
    {
        $this->conditions['type'] = 0;

        // 添加卡属性匹配查找
        if (isset($this->conditions['prop_product']) || isset($this->conditions['prop_package'])) {
            CardService::propConditions($this->conditions);
        }

        return app(OrderCardRepository::class)->selectRaw("COUNT(*) AS count")->withConditions($this->conditions)->first()->count;
    }

    public function query()
    {
        $this->conditions['type'] = 0;

        // 添加卡属性匹配查找
        if (isset($this->conditions['prop_product']) || isset($this->conditions['prop_package'])) {
            CardService::propConditions($this->conditions);
        }

        $select = [
            'id',
            'sim',
            'company_id',
            'package_id',
            'created_at',
            'updated_at',
        ];

        $builder = app(OrderCardRepository::class)->forceNoReset()->skipCache()->select($select)->withConditions($this->conditions)->orderBy('created_at', 'desc');

        return $builder;
    }

    /**
     * @param mixed $row
     *
     * @return mixed
     */
    public function rows($rows)
    {
        $rows = CardService::transformer(new Collection($rows));

        $array = [];

        foreach ($rows as $item) {
            $array[] = [
                $item['id'],
                $item['sim']."\t",
                $item['imsi']."\t",
                $item['iccid']."\t",
                $item['carrier_operator'],
                $item['company_name'],
                $item['package_name'],
                $item['prop_product'],
                $item['prop_package'],
                $item['virtual_activated_at'],
                $item['status_name'],
                $item['created_at'],
                $item['service_start_at'],
                $item['service_end_at'],
            ];
        }

        return $array;
    }

    public function headings(): array
    {
        return [
            '客户编号',
            'SIM',
            'IMSI',
            'ICCID',
            '运营商',
            '企业名称',
            '套餐名称',
            '产品类型',
            '套餐类型',
            '激活时间',
            '状态',
            '创建时间',
            '服务开始时间',
            '服务结束时间',
        ];
    }

    /**
     * @return array
     */
    public function columnFormats(): array
    {
        return [
            'H' => NumberFormat::FORMAT_DATE_YYYYMMDD2,
            'J' => NumberFormat::FORMAT_DATE_YYYYMMDD2,
        ];
    }
}
