<?php

namespace app\common\model;

use app\common\model\traits\TimestampInteger;
use support\think\Db;
use support\think\Model;

/**
 * MallAddress
 */
class MallAddress extends Model
{
    use TimestampInteger;

    // 表名
    protected $name = 'mall_address';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = true;

    // 追加属性
    protected $append = [
        'region_text',
    ];

    /**
     * 表单展示：文本地区返回规范化字符串；历史地区 ID 转为名称（英文逗号拼接）
     */
    public function getregionAttr($value): string
    {
        if ($value === '' || $value === null) {
            return '';
        }
        if (is_array($value)) {
            return self::normalizeRegion($value);
        }
        $region = trim(strval($value));
        if ($region === '') {
            return '';
        }
        if (self::isAreaIdList($region)) {
            return self::resolveAreaNames($region);
        }
        return self::normalizeRegion($region);
    }

    /**
     * 入库：统一为英文逗号分隔（与 API / 原 city 组件存储格式一致）
     */
    public function setregionAttr($value): string
    {
        return self::normalizeRegion($value);
    }

    public function getregionTextAttr($value, $row): string
    {
        $region = $row['region'] ?? '';
        if ($region === '' || $region === null) {
            return '';
        }
        if (is_array($region)) {
            return self::normalizeRegion($region);
        }
        $region = trim(strval($region));
        if ($region === '') {
            return '';
        }
        if (self::isAreaIdList($region)) {
            return self::resolveAreaNames($region);
        }
        return self::normalizeRegion($region);
    }

    /**
     * 将地区规范为英文逗号分隔字符串（数组或「省,市,区」文本）
     */
    public static function normalizeRegion(mixed $value): string
    {
        if (is_array($value)) {
            $parts = [];
            foreach ($value as $item) {
                $part = trim(strval($item));
                if ($part !== '') {
                    $parts[] = $part;
                }
            }
            return implode(',', $parts);
        }

        $region = trim(strval($value));
        if ($region === '') {
            return '';
        }

        $region = str_replace('，', ',', $region);
        $parts = explode(',', $region);
        $normalized = [];
        foreach ($parts as $part) {
            $part = trim($part);
            if ($part !== '') {
                $normalized[] = $part;
            }
        }

        return implode(',', $normalized);
    }

    public static function isAreaIdList(string $region): bool
    {
        $parts = array_values(array_filter(array_map('trim', explode(',', $region)), static function ($part) {
            return $part !== '';
        }));
        if ($parts === []) {
            return false;
        }
        foreach ($parts as $part) {
            if (!ctype_digit($part)) {
                return false;
            }
        }
        return true;
    }

    public static function resolveAreaNames(string $region): string
    {
        $ids = array_values(array_filter(array_map('trim', explode(',', $region)), static function ($part) {
            return $part !== '';
        }));
        if ($ids === []) {
            return '';
        }
        $cityNames = Db::name('area')->whereIn('id', $ids)->column('name');
        if (!$cityNames) {
            return self::normalizeRegion($region);
        }
        return implode(',', $cityNames);
    }

    public function playxUserAsset(): \think\model\relation\BelongsTo
    {
        return $this->belongsTo(\app\common\model\MallUserAsset::class, 'playx_user_asset_id', 'id');
    }

    /**
     * 实物订单收货快照（写入 mall_order.receiver_*，与 mall_address 当前内容一致）
     *
     * @return array{receiver_name: string, receiver_phone: string, receiver_address: string}
     */
    public static function snapshotForPhysicalOrder(self $addr): array
    {
        $regionText = $addr->region_text ?? '';
        $parts = array_filter([
            trim($regionText),
            trim($addr->detail_address ?? ''),
        ], static function ($s) {
            return $s !== '';
        });
        $receiverAddress = implode(' ', $parts);

        return [
            'receiver_name'    => trim($addr->receiver_name ?? ''),
            'receiver_phone'   => trim($addr->phone ?? ''),
            'receiver_address' => $receiverAddress,
        ];
    }
}
