<?php
namespace app\plugins\vr_ticket\hook;

use think\facade\Db;
use app\plugins\vr_ticket\service\SeatSkuService;

class AdminGoodsSaveHandle
{
    /**
     * 商品保存钩子（同时响应 save_handle 和 save_thing_end 两个时机）
     */
    public function handle($params = [])
    {
        $hookName = $params['hook_name'] ?? '';

        // ──────────────────────────────────────────────────────
        // 时机 1：plugins_service_goods_save_handle（事务前，修改待保存数据）
        //   - 把 vr_goods_config base64 解码写入 $data
        //   - 设置 item_type
        //   - 强制 is_exist_many_spec = 1
        // ──────────────────────────────────────────────────────
        if ($hookName === 'plugins_service_goods_save_handle') {
            $postParams = $params['params'] ?? [];

            if (isset($postParams['vr_is_ticket']) && $postParams['vr_is_ticket'] == 1) {
                $params['data']['item_type'] = 'ticket';
                $params['data']['is_exist_many_spec'] = 1;

                $base64Config = $postParams['vr_goods_config_base64'] ?? '';
                if (!empty($base64Config)) {
                    $jsonStr = base64_decode($base64Config);
                    if ($jsonStr !== false) {
                        $params['data']['vr_goods_config'] = $jsonStr;
                    }
                }
            } else {
                $params['data']['item_type'] = 'normal';
                $params['data']['vr_goods_config'] = '';
            }

            return ['code' => 0];
        }

        // ──────────────────────────────────────────────────────
        // 时机 2：plugins_service_goods_save_thing_end（事务内，goods 已落表）
        //   关键：此时 GoodsSpecificationsInsert + GoodsSaveBaseUpdate
        //   已经执行完毕（它们处理的是表单原生规格数据）。
        //
        //   对于票务商品，我们需要：
        //     a) 删除原生流程产生的所有 spec 数据（表单垃圾）
        //     b) 用 BatchGenerate 重新生成 VR 座位级 SKU
        //     c) 回写 GoodsSpecType.value（让后台正确展示）
        //     d) 重新计算 goods 表的 price/inventory
        // ──────────────────────────────────────────────────────
        if ($hookName === 'plugins_service_goods_save_thing_end') {
            $data    = $params['data']     ?? [];
            $goodsId = $params['goods_id'] ?? 0;

            if ($goodsId > 0 && ($data['item_type'] ?? '') === 'ticket') {
                // 直接从数据库读 vr_goods_config（全量查询，不加 field 限制，避免 ThinkPHP 软删除过滤导致查不到）
                // 前端已过滤无效 template_id，优先使用 data。若无前端数据再 fallback 到 DB
                if (!empty($data['vr_goods_config'])) {
                    $rawConfig = $data['vr_goods_config'];
                } else {
                    $rawConfig = is_array($goodsRow) ? ($goodsRow['vr_goods_config'] ?? '') : '';
                }

                if (!empty($rawConfig)) {
                    $configs = json_decode($rawConfig, true);
                    if (json_last_error() !== JSON_ERROR_NONE) {
                        $configs = null;
                    }

                    if (is_array($configs) && !empty($configs)) {
                            // 0) 重建 template_snapshot — 前端不发送 template_snapshot，
                            //    当 template_snapshot 为空、或 selected_rooms 有值时，从 DB 重建
                            foreach ($configs as $i => &$config) {
                                $templateId    = intval($config['template_id'] ?? 0);
                                $selectedRooms = $config['selected_rooms'] ?? [];

                                // 条件：snapshot 为空，或者前端有 selected_rooms
                                if ($templateId > 0 && (!empty($selectedRooms) || empty($config['template_snapshot']) || empty($config['template_snapshot']['rooms']))) {
                                    $template = Db::name('vr_seat_templates')->find($templateId);

                                    // 模板不存在时（硬删除场景）：
                                    // - 移除无效 config 块，避免脏数据写回
                                    // - 前端下次打开时将看到选单为空，用户可重新选择或清空配置
                                    if (empty($template)) {
                                        unset($configs[$i]);  // 移除无效 config 块
                                        continue;
                                    }


                                    $seatMap  = json_decode($template['seat_map'] ?? '{}', true);
                                    $allRooms = $seatMap['rooms'] ?? [];
                                    // 注意：v3 格式 room.id 可能为空（用数组索引代替 id），
                                    //       此时 room_0 对应 rooms[0]，room_1 对应 rooms[1]，以此类推
                                    // ── v1→v3 兼容迁移 ──
                                    if (empty($allRooms) && !empty($seatMap['sections'])) {
                                        $v1Sections = $seatMap['sections'] ?? [];
                                        $v1Map      = $seatMap['map'] ?? [];
                                        $v1Seats    = $seatMap['seats'] ?? [];
                                        $v1RoomId   = $selectedRooms[0] ?? 'room_1';
                                        $allRooms = [[
                                            'id'       => $v1RoomId,
                                            'name'     => $seatMap['venue']['name'] ?? '主馆',
                                            'sections' => $v1Sections,
                                            'map'      => $v1Map,
                                            'seats'    => $v1Seats,
                                        ]];
                                    }

                                    // 按 selected_rooms 过滤（支持前端标准化的 "room_0" 格式双向兼容）
                                    // 注意：v3 格式 room.id 可能为空（用数组索引代替 id），
                                    //       此时 room_0 对应 rooms[0]，room_1 对应 rooms[1]，以此类推
                                    $selectedRoomIds = array_column(
                                        array_filter($allRooms, function ($r) use ($selectedRooms) {
                                            $rid = $r['id'] ?? '';
                                            // 直接匹配
                                            if (in_array($rid, $selectedRooms)) {
                                                return true;
                                            }
                                            // 尝试加/减 "room_" 前缀匹配（PHP 7.x 兼容）
                                            if (strpos($rid, 'room_') === 0 && in_array(substr($rid, 5), $selectedRooms)) {
                                                return true;
                                            }
                                            if (!empty($rid) && in_array('room_' . $rid, $selectedRooms)) {
                                                return true;
                                            }
                                            // 空 id：用数组索引替代（room_0→rooms[0], room_1→rooms[1]）
                                            static $roomIndex = -1;
                                            $roomIndex++;
                                            if ($rid === '' && in_array('room_' . $roomIndex, $selectedRooms)) {
                                                return true;
                                            }
                                            return false;
                                        }), null
                                    );

                                    $config['template_snapshot'] = [
                                        'venue' => $seatMap['venue'] ?? [],
                                        'rooms' => $selectedRoomIds,
                                    ];
                                }
                            }
                            unset($config);  // 解除引用，避免后续误改
                            $configs = array_values($configs);  // 重排数组索引

                            // 将填充后的完整 config 写回 goods 表（仅在有有效配置时）
                            if (!empty($configs)) {
                                Db::name('Goods')->where('id', $goodsId)->update([
                                    'vr_goods_config' => json_encode($configs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
                                ]);
                            }

                            // a) 清空原生规格数据 —— 避免列偏移
                            Db::name('GoodsSpecType')->where('goods_id', $goodsId)->delete();
                            Db::name('GoodsSpecBase')->where('goods_id', $goodsId)->delete();
                            Db::name('GoodsSpecValue')->where('goods_id', $goodsId)->delete();

                            // b) 逐模板生成 VR SKU（ensureAndFillVrSpecTypes 在内部调用，type.value 同步写入）
                            foreach ($configs as $config) {
                                $templateId       = intval($config['template_id'] ?? 0);
                                $selectedRooms    = $config['selected_rooms']    ?? [];
                                $selectedSections = $config['selected_sections'] ?? [];
                                $sessions         = $config['sessions']          ?? [];

                                if ($templateId > 0) {
                                    $res = SeatSkuService::BatchGenerate(
                                        $goodsId, $templateId,
                                        $selectedRooms, $selectedSections, $sessions
                                    );
                                    if ($res['code'] !== 0) {
                                        return $res;
                                    }
                                }
                            }

                            // c) 重新计算 goods.price / goods.inventory
                            SeatSkuService::refreshGoodsBase($goodsId);
                        }
                }
            }

            return ['code' => 0];
        }

        return ['code' => 0];
    }
}
