<?php

declare(strict_types=1);

namespace app\admin\controller\mall;

use app\common\controller\Backend;
use app\common\library\MallPlayxRatios;
use app\common\library\MallPointsConversion;
use app\common\model\MallBusinessConfig;
use support\Response;
use support\think\Db;
use Webman\Http\Request;

/**
 * 积分商城参数（PlayX 比例等，读写 mall_business_config）
 */
class PlayxConfig extends Backend
{
    public function index(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) {
            return $response;
        }

        $row = MallBusinessConfig::ensureRow();

        MallPlayxRatios::syncFromRow($row);

        $payload = $row->toArray();
        $payload['active_mall_open_date'] = MallPointsConversion::resolveActiveMallOpenDate($row);

        return $this->success('', [
            'row'    => $payload,
            'remark' => get_route_remark(),
        ]);
    }

    public function save(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) {
            return $response;
        }

        $data = $request->post();
        if (empty($data) || !is_array($data)) {
            return $this->error(__('Parameter %s can not be empty', ['']));
        }

        $return = $data['return_ratio'] ?? null;
        $unlock = $data['unlock_ratio'] ?? null;
        $cash = $data['points_to_cash_ratio'] ?? null;
        if (!is_numeric($return) || !is_numeric($unlock) || !is_numeric($cash)) {
            return $this->error(__('Parameter error'));
        }

        $returnF = floatval($return);
        $unlockF = floatval($unlock);
        $cashF = floatval($cash);
        if ($returnF < 0 || $unlockF < 0 || $cashF < 0) {
            return $this->error(__('Parameter error'));
        }

        $dailyEnabled = !empty($data['daily_points_enabled']) ? 1 : 0;
        $lifetimeEnabled = !empty($data['lifetime_points_enabled']) ? 1 : 0;
        $lifetimeRatio = $data['lifetime_points_ratio'] ?? null;
        if (!is_numeric($lifetimeRatio)) {
            return $this->error(__('Parameter error'));
        }
        $lifetimeRatioF = floatval($lifetimeRatio);
        if ($lifetimeRatioF < 0) {
            return $this->error(__('Parameter error'));
        }

        $mallOpenDate = MallPointsConversion::normalizeDate($data['mall_open_date'] ?? null);

        $row = MallBusinessConfig::order('id', 'asc')->find();
        $now = time();
        if (!$row) {
            $effectiveOn = $mallOpenDate !== null ? MallPointsConversion::nextCalendarDate() : null;
            MallBusinessConfig::create([
                'return_ratio'                    => $returnF,
                'unlock_ratio'                    => $unlockF,
                'points_to_cash_ratio'            => $cashF,
                'daily_points_enabled'            => $dailyEnabled,
                'lifetime_points_enabled'         => $lifetimeEnabled,
                'lifetime_points_ratio'           => $lifetimeRatioF,
                'mall_open_date'                  => $mallOpenDate,
                'mall_open_date_previous'         => null,
                'mall_open_date_effective_on'     => $effectiveOn,
                'create_time'                     => $now,
                'update_time'                     => $now,
            ]);
        } else {
            $previousOpen = MallPointsConversion::resolveActiveMallOpenDate($row);
            $currentPending = MallPointsConversion::normalizeDate($row->mall_open_date ?? null);
            $openDateChanged = $mallOpenDate !== $currentPending;

            $row->return_ratio = $returnF;
            $row->unlock_ratio = $unlockF;
            $row->points_to_cash_ratio = $cashF;
            $row->daily_points_enabled = $dailyEnabled;
            $row->lifetime_points_enabled = $lifetimeEnabled;
            $row->lifetime_points_ratio = $lifetimeRatioF;

            if ($openDateChanged) {
                $row->mall_open_date_previous = $previousOpen;
                $row->mall_open_date = $mallOpenDate;
                $row->mall_open_date_effective_on = $mallOpenDate !== null ? MallPointsConversion::nextCalendarDate() : null;
            }

            $row->save();
        }

        $fresh = MallBusinessConfig::order('id', 'asc')->find();
        if ($fresh) {
            MallPlayxRatios::syncFromRow($fresh);
        }

        return $this->success(__('The current page configuration item was updated successfully'));
    }

    /**
     * 一键按最新终身总输赢与比例折算积分（重复执行会先扣旧比例再加新比例）
     */
    public function calculateLifetimePoints(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) {
            return $response;
        }

        $row = MallBusinessConfig::order('id', 'asc')->find();
        if (!$row) {
            return $this->error(__('Parameter error'));
        }

        Db::startTrans();
        try {
            $stats = MallPointsConversion::recalculateAllLifetimePoints($row);
            Db::commit();
        } catch (\Throwable $e) {
            Db::rollback();

            return $this->error(__($e->getMessage()));
        }

        return $this->success(
            sprintf(
                __('Lifetime points calculation completed'),
                $stats['processed'],
                $stats['updated'],
                $stats['skipped']
            ),
            $stats
        );
    }
}
