<?php

namespace app\admin\controller\mall;

use Throwable;
use app\common\library\MallDailyPushBackfill;
use app\common\library\MallDailyPushExport;
use app\common\controller\Backend;
use support\Response;
use Webman\Http\Request;

/**
 * 每日推送数据（后台列表）
 */
class DailyPush extends Backend
{
    /**
     * @var object|null
     * @phpstan-var \app\common\model\MallDailyPush|null
     */
    protected ?object $model = null;

    protected array|string $preExcludeFields = ['id', 'create_time', 'update_time'];

    protected string|array $quickSearchField = ['user_id', 'username', 'date'];

    protected string|array $indexField = [
        'id',
        'user_id',
        'date',
        'username',
        'yesterday_win_loss_net',
        'yesterday_total_deposit',
        'lifetime_total_deposit',
        'lifetime_total_withdraw',
        'create_time',
    ];

    /**
     * exportCount 与 export 共用导出权限
     */
    protected array $noNeedPermission = ['exportCount'];

    public function initialize(): void
    {
        parent::initialize();
        $this->model = new \app\common\model\MallDailyPush();
    }

    /**
     * 查看
     * @throws Throwable
     */
    public function index(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) {
            return $response;
        }

        if ($request->get('select') || $request->post('select')) {
            return $this->select($request);
        }

        return $this->_index();
    }

    /**
     * 导出筛选结果条数预览
     */
    public function exportCount(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) {
            return $response;
        }

        if (!$this->auth->check('mall/dailyPush/export')) {
            return $this->error(__('You have no permission'), [], 401);
        }

        try {
            [$where, $alias] = $this->buildExportQueryParts();
            $count = $this->model->alias($alias)->where($where)->count();
            $exporter = new MallDailyPushExport();
            return $this->success('', [
                'count'     => $count,
                'max_limit' => $exporter->getMaxExportLimit(),
            ]);
        } catch (Throwable $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 导出 Excel（XLSX 流式写入）
     */
    public function export(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) {
            return $response;
        }

        $fieldsRaw = $request->post('fields', $request->get('fields', []));
        $fields = is_array($fieldsRaw) ? $fieldsRaw : explode(',', strval($fieldsRaw));
        $limitRaw = strval($request->post('export_limit', $request->get('export_limit', '0')));
        if (!is_numeric($limitRaw)) {
            return $this->error(__('Parameter error'));
        }
        $limit = intval($limitRaw);
        if ($limit < 0) {
            return $this->error(__('Parameter error'));
        }

        try {
            [$where, $alias, $order] = $this->buildExportQueryParts();
            $lang = strval($request->header('think-lang', 'zh-cn'));
            $exporter = new MallDailyPushExport();
            return $exporter->export($this->model, $where, $alias, $order, $fields, $limit, $lang);
        } catch (Throwable $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * @return array{0: array, 1: array, 2: array}
     */
    private function buildExportQueryParts(): array
    {
        [$where, $alias, , $order] = $this->queryBuilder();
        return [$where, $alias, $order];
    }

    /**
     * 按历史 mall_daily_push 记录回补用户信息
     */
    public function backfillUsers(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) {
            return $response;
        }

        $dateFrom = trim(strval($request->post('date_from', $request->get('date_from', ''))));
        $dateTo = trim(strval($request->post('date_to', $request->get('date_to', ''))));
        $limitRaw = strval($request->post('limit', $request->get('limit', '0')));
        $dryRunRaw = strval($request->post('dry_run', $request->get('dry_run', '0')));

        if ($dateFrom !== '' && !$this->isValidDate($dateFrom)) {
            return $this->error('date_from 格式错误，需为 YYYY-MM-DD');
        }
        if ($dateTo !== '' && !$this->isValidDate($dateTo)) {
            return $this->error('date_to 格式错误，需为 YYYY-MM-DD');
        }
        if (!is_numeric($limitRaw)) {
            return $this->error('limit 必须是数字');
        }
        $limit = intval($limitRaw);
        if ($limit < 0) {
            return $this->error('limit 不能小于 0');
        }
        $dryRun = in_array(strtolower($dryRunRaw), ['1', 'true', 'yes', 'on'], true);

        $service = new MallDailyPushBackfill();
        $result = $service->backfill(
            $dateFrom === '' ? null : $dateFrom,
            $dateTo === '' ? null : $dateTo,
            $limit,
            $dryRun
        );

        return $this->success('', $result);
    }

    private function isValidDate(string $value): bool
    {
        $dt = \DateTime::createFromFormat('Y-m-d', $value);
        if (!$dt) {
            return false;
        }
        return $dt->format('Y-m-d') === $value;
    }
}

