<?php

declare(strict_types=1);

namespace app\common\service;

use app\common\database\Dm;
use think\facade\Db;

/** Response-only fixed-scale fields for merchant and terminal order reads. */
final class OrderReadResponse
{
    private static function fields(array $row, array $names): array
    {
        if (!(Db::connect() instanceof Dm)) return $row;
        foreach ($names as $name) {
            if (!array_key_exists($name, $row)) continue;
            $value = $row[$name];
            // These exact DTO paths originate from DECIMAL(10,2), never wide DECIMAL.
            if ((!is_int($value) && !is_float($value))
                || (is_float($value) && !is_finite($value))
                || abs($value) > 99999999.99
                || abs($value - round($value, 2)) > 0.0000001) continue;
            $row[$name] = FixedScaleDecimalResponse::fields([$name => $value], [$name])[$name];
        }
        return $row;
    }

    private const USER_MONEY = [
        'balance', 'withdrawable_balance', 'activity_principal_balance',
        'subsidy_balance', 'gift_balance', 'pay_money', 'expend_money',
    ];

    public static function orderDetail(array $row): array
    {
        $row = self::fields($row, [
            'total_price', 'coupon_money', 'points_money', 'pay_price', 'express_price',
        ]);
        if (isset($row['user']) && is_array($row['user'])) {
            $row['user'] = self::fields($row['user'], self::USER_MONEY);
        }
        if (isset($row['goods']) && is_array($row['goods'])) {
            foreach ($row['goods'] as &$goods) {
                if (is_array($goods)) {
                    $goods = self::fields($goods, [
                        'goods_price', 'line_price', 'grade_goods_price', 'grade_total_money',
                        'coupon_money', 'points_money', 'total_price', 'total_pay_price',
                    ]);
                }
            }
            unset($goods);
        }
        return $row;
    }

    public static function orderList(array $page): array
    {
        if (isset($page['data']) && is_array($page['data'])) {
            foreach ($page['data'] as &$row) {
                if (is_array($row)) $row = self::orderDetail($row);
            }
            unset($row);
        }
        return $page;
    }

    public static function rechargeList(array $page): array
    {
        if (isset($page['data']) && is_array($page['data'])) {
            foreach ($page['data'] as &$row) {
                if (!is_array($row)) continue;
                $row = self::fields($row, [
                    'pay_price', 'gift_money', 'actual_money', 'withdrawable_amount',
                    'activity_principal_amount', 'recharg_before', 'recharg_after',
                    'refund_money', 'use_money', 'refundable_money',
                ]);
                if (isset($row['user']) && is_array($row['user'])) {
                    $row['user'] = self::fields($row['user'], self::USER_MONEY);
                }
                if (isset($row['order_plan']) && is_array($row['order_plan'])) {
                    $row['order_plan'] = self::fields($row['order_plan'], ['money', 'gift_money']);
                }
            }
            unset($row);
        }
        return $page;
    }

    public static function deliveryList(array $page): array
    {
        if (isset($page['data']) && is_array($page['data'])) {
            foreach ($page['data'] as &$row) {
                if (!is_array($row)) continue;
                if (isset($row['orderData']) && is_array($row['orderData'])) {
                    $row['orderData'] = self::orderDetail($row['orderData']);
                }
                if (isset($row['goods']) && is_array($row['goods'])) {
                    foreach ($row['goods'] as &$item) {
                        if (is_array($item) && isset($item['goods']) && is_array($item['goods'])) {
                            $item['goods'] = self::fields($item['goods'], [
                                'goods_price', 'line_price', 'grade_goods_price', 'grade_total_money',
                                'coupon_money', 'points_money', 'total_price', 'total_pay_price',
                            ]);
                        }
                    }
                    unset($item);
                }
            }
            unset($row);
        }
        return $page;
    }

    public static function refundDetail(array $row): array
    {
        $row = self::fields($row, ['refund_money']);
        if (isset($row['orderData']) && is_array($row['orderData'])) {
            $row['orderData'] = self::orderDetail($row['orderData']);
        }
        if (isset($row['orderGoods']) && is_array($row['orderGoods'])) {
            $row['orderGoods'] = self::fields($row['orderGoods'], [
                'goods_price', 'line_price', 'grade_goods_price', 'grade_total_money',
                'coupon_money', 'points_money', 'total_price', 'total_pay_price',
            ]);
        }
        if (isset($row['user']) && is_array($row['user'])) {
            $row['user'] = self::fields($row['user'], self::USER_MONEY);
        }
        return $row;
    }

    public static function refundList(array $page): array
    {
        if (isset($page['data']) && is_array($page['data'])) {
            foreach ($page['data'] as &$row) {
                if (is_array($row)) $row = self::refundDetail($row);
            }
            unset($row);
        }
        return $page;
    }

}
