<?php

namespace App\Services;

use App\Apps\CmsproChildrehab\Models\AdminUserHospital;
use App\Http\Responses\ApiResponse;
use App\Models\AdminUserExtData;
use App\Models\AdminUserExtField;
use App\Models\UserExtData;
use App\Models\UserExtField;
use Illuminate\Support\Facades\DB;

/**
 * 用户扩展字段服务
 *
 * 统一管理后台用户和前台用户的扩展字段定义与数据。
 * 支持字段定义的CRUD、用户扩展数据的读写、应用卸载时的清理。
 */
class UserExtFieldService
{
    // ========== 字段定义管理 ==========

    /**
     * 获取后台用户扩展字段列表
     */
    public function listAdminFields(): array
    {
        $fields = AdminUserExtField::orderBy('sort', 'asc')->orderBy('id', 'asc')->get();

        return ApiResponse::success($fields);
    }

    /**
     * 获取前台用户扩展字段列表
     */
    public function listUserFields(): array
    {
        $fields = UserExtField::orderBy('sort', 'asc')->orderBy('id', 'asc')->get();

        return ApiResponse::success($fields);
    }

    /**
     * 创建后台用户扩展字段
     */
    public function storeAdminField(array $data): array
    {
        if (AdminUserExtField::where('field_name', $data['field_name'])->exists()) {
            return ApiResponse::error(40001, '字段标识已存在');
        }

        $field = AdminUserExtField::create([
            'field_name' => $data['field_name'],
            'field_label' => $data['field_label'],
            'field_type' => $data['field_type'] ?? 'text',
            'field_options' => $data['field_options'] ?? null,
            'app_id' => $data['app_id'] ?? null,
            'sort' => $data['sort'] ?? 0,
            'status' => $data['status'] ?? 1,
        ]);

        return ApiResponse::success($field, '创建成功');
    }

    /**
     * 创建前台用户扩展字段
     */
    public function storeUserField(array $data): array
    {
        if (UserExtField::where('field_name', $data['field_name'])->exists()) {
            return ApiResponse::error(40001, '字段标识已存在');
        }

        $field = UserExtField::create([
            'field_name' => $data['field_name'],
            'field_label' => $data['field_label'],
            'field_type' => $data['field_type'] ?? 'text',
            'field_options' => $data['field_options'] ?? null,
            'app_id' => $data['app_id'] ?? null,
            'sort' => $data['sort'] ?? 0,
            'status' => $data['status'] ?? 1,
        ]);

        return ApiResponse::success($field, '创建成功');
    }

    /**
     * 更新后台用户扩展字段
     */
    public function updateAdminField(int $id, array $data): array
    {
        $field = AdminUserExtField::find($id);
        if (!$field) {
            return ApiResponse::error(40401, '字段不存在');
        }

        // 检查字段标识唯一性（排除自身）
        if (isset($data['field_name']) && $data['field_name'] !== $field->field_name) {
            if (AdminUserExtField::where('field_name', $data['field_name'])->exists()) {
                return ApiResponse::error(40001, '字段标识已存在');
            }
        }

        $field->update([
            'field_name' => $data['field_name'] ?? $field->field_name,
            'field_label' => $data['field_label'] ?? $field->field_label,
            'field_type' => $data['field_type'] ?? $field->field_type,
            'field_options' => $data['field_options'] ?? $field->field_options,
            'sort' => $data['sort'] ?? $field->sort,
            'status' => $data['status'] ?? $field->status,
        ]);

        return ApiResponse::success($field, '更新成功');
    }

    /**
     * 更新前台用户扩展字段
     */
    public function updateUserField(int $id, array $data): array
    {
        $field = UserExtField::find($id);
        if (!$field) {
            return ApiResponse::error(40401, '字段不存在');
        }

        if (isset($data['field_name']) && $data['field_name'] !== $field->field_name) {
            if (UserExtField::where('field_name', $data['field_name'])->exists()) {
                return ApiResponse::error(40001, '字段标识已存在');
            }
        }

        $field->update([
            'field_name' => $data['field_name'] ?? $field->field_name,
            'field_label' => $data['field_label'] ?? $field->field_label,
            'field_type' => $data['field_type'] ?? $field->field_type,
            'field_options' => $data['field_options'] ?? $field->field_options,
            'sort' => $data['sort'] ?? $field->sort,
            'status' => $data['status'] ?? $field->status,
        ]);

        return ApiResponse::success($field, '更新成功');
    }

    /**
     * 删除后台用户扩展字段（含数据）
     */
    public function destroyAdminField(int $id): array
    {
        $field = AdminUserExtField::find($id);
        if (!$field) {
            return ApiResponse::error(40401, '字段不存在');
        }

        DB::transaction(function () use ($field) {
            AdminUserExtData::where('field_id', $field->id)->delete();
            $field->delete();
        });

        return ApiResponse::success(null, '删除成功');
    }

    /**
     * 删除前台用户扩展字段（含数据）
     */
    public function destroyUserField(int $id): array
    {
        $field = UserExtField::find($id);
        if (!$field) {
            return ApiResponse::error(40401, '字段不存在');
        }

        DB::transaction(function () use ($field) {
            UserExtData::where('field_id', $field->id)->delete();
            $field->delete();
        });

        return ApiResponse::success(null, '删除成功');
    }

    // ========== 扩展数据读写 ==========

    /**
     * 获取后台用户扩展数据（以 field_name => field_value 形式返回）
     *
     * hospital_id 字段优先从 admin_user_hospitals 关联表读取，
     * 确保医院管理页面和用户表单的数据一致。
     */
    public function getAdminUserExtData(int $adminUserId): array
    {
        $fields = AdminUserExtField::enabled()->orderBy('sort')->get();
        $dataMap = AdminUserExtData::where('admin_user_id', $adminUserId)
            ->get()
            ->keyBy('field_id');

        // 从关联表读取医院绑定
        $hospitalBindings = AdminUserHospital::where('admin_user_id', $adminUserId)
            ->pluck('hospital_id')
            ->map(fn($id) => (string) $id)
            ->values()
            ->toArray();

        $result = [];
        foreach ($fields as $field) {
            // hospital_id 字段优先从关联表读取
            if ($field->field_name === 'hospital_id' && $field->field_type === 'select') {
                $result[$field->field_name] = $hospitalBindings;
                continue;
            }

            $rawValue = $dataMap->has($field->id) ? $dataMap[$field->id]->field_value : null;
            $fieldOptions = $field->field_options;
            // 多选字段：JSON 解码为数组
            if ($rawValue !== null && is_array($fieldOptions) && ($fieldOptions['multiple'] ?? false)) {
                $decoded = json_decode($rawValue, true);
                $result[$field->field_name] = is_array($decoded) ? $decoded : [];
            } else {
                $result[$field->field_name] = $rawValue;
            }
        }

        return $result;
    }

    /**
     * 获取前台用户扩展数据
     */
    public function getUserExtData(int $userId): array
    {
        $fields = UserExtField::enabled()->orderBy('sort')->get();
        $dataMap = UserExtData::where('user_id', $userId)
            ->get()
            ->keyBy('field_id');

        $result = [];
        foreach ($fields as $field) {
            $rawValue = $dataMap->has($field->id) ? $dataMap[$field->id]->field_value : null;
            $fieldOptions = $field->field_options;
            // 多选字段：JSON 解码为数组
            if ($rawValue !== null && is_array($fieldOptions) && ($fieldOptions['multiple'] ?? false)) {
                $decoded = json_decode($rawValue, true);
                $result[$field->field_name] = is_array($decoded) ? $decoded : [];
            } else {
                $result[$field->field_name] = $rawValue;
            }
        }

        return $result;
    }

    /**
     * 保存后台用户扩展数据
     *
     * @param int $adminUserId
     * @param array $extData field_name => field_value 形式
     */
    public function saveAdminUserExtData(int $adminUserId, array $extData): void
    {
        $fields = AdminUserExtField::enabled()->get()->keyBy('field_name');

        foreach ($extData as $fieldName => $value) {
            if (!$fields->has($fieldName)) {
                continue;
            }

            $field = $fields[$fieldName];
            // 多选场景：数组值 JSON 编码后存储
            $storedValue = is_array($value) ? json_encode($value) : $value;
            AdminUserExtData::updateOrCreate(
                ['admin_user_id' => $adminUserId, 'field_id' => $field->id],
                ['field_value' => $storedValue]
            );
        }
    }

    /**
     * 保存前台用户扩展数据
     */
    public function saveUserExtData(int $userId, array $extData): void
    {
        $fields = UserExtField::enabled()->get()->keyBy('field_name');

        foreach ($extData as $fieldName => $value) {
            if (!$fields->has($fieldName)) {
                continue;
            }

            $field = $fields[$fieldName];
            // 多选场景：数组值 JSON 编码后存储
            $storedValue = is_array($value) ? json_encode($value) : $value;
            UserExtData::updateOrCreate(
                ['user_id' => $userId, 'field_id' => $field->id],
                ['field_value' => $storedValue]
            );
        }
    }

    // ========== 应用卸载清理 ==========

    /**
     * 清理指定应用创建的后台用户扩展字段和数据
     */
    public function cleanAdminExtByApp(string $appId): int
    {
        $fieldIds = AdminUserExtField::where('app_id', $appId)->pluck('id');
        if ($fieldIds->isEmpty()) {
            return 0;
        }

        AdminUserExtData::whereIn('field_id', $fieldIds)->delete();
        AdminUserExtField::where('app_id', $appId)->delete();

        return $fieldIds->count();
    }

    /**
     * 清理指定应用创建的前台用户扩展字段和数据
     */
    public function cleanUserExtByApp(string $appId): int
    {
        $fieldIds = UserExtField::where('app_id', $appId)->pluck('id');
        if ($fieldIds->isEmpty()) {
            return 0;
        }

        UserExtData::whereIn('field_id', $fieldIds)->delete();
        UserExtField::where('app_id', $appId)->delete();

        return $fieldIds->count();
    }
}
