<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>前台用户表单</title>
    <link rel="stylesheet" href="/CmsProUi/component/pear/css/pear.css" />
    <link rel="stylesheet" href="/CmsProUi/font-awesome/4.7.0/css/font-awesome.min.css" />
    <link rel="stylesheet" href="/Admin/css/admin.css" />
    <link rel="stylesheet" href="/Admin/css/variables.css" />
    <link rel="stylesheet" href="/Admin/css/reset.css" />
</head>
<style>
    .layui-form-label {
        padding: 9px 4px;
        width: unset;
    }
    .layui-input, .layui-textarea {
        width: 98%;
    }
    html, body {
        height: 100%;
        margin: 0;
        overflow: hidden;
    }
    .layui-row {
        height: calc(100vh - 52px);
        overflow-y: auto;
    }
    .bottom {
        height: 52px;
    }
</style>

<body>
    <form class="layui-form" action="">
        <input type="hidden" id="id" name="id" value="">
        <div class="layui-row">
            <div class="layui-col-md12">
                <div class="layui-card-body layui-row">
                    <div class="layui-col-md12">
                        <div class="layui-form-item">
                            <label class="layui-form-label">用户名</label>
                            <div class="layui-input-block">
                                <input type="text" id="username" name="username" lay-verify="required" lay-reqText="用户名不能为空" placeholder="4-20位字母数字下划线" class="layui-input" autocomplete="off">
                            </div>
                        </div>
                        <div class="layui-form-item" id="password-item">
                            <label class="layui-form-label">密码</label>
                            <div class="layui-input-block">
                                <input type="password" id="password" name="password" placeholder="6-20位" class="layui-input" autocomplete="off">
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">昵称</label>
                            <div class="layui-input-block">
                                <input type="text" id="nickname" name="nickname" placeholder="请输入昵称" class="layui-input" autocomplete="off">
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">邮箱</label>
                            <div class="layui-input-block">
                                <input type="text" id="email" name="email" placeholder="请输入邮箱" class="layui-input" autocomplete="off">
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">手机号</label>
                            <div class="layui-input-block">
                                <input type="text" id="phone" name="phone" placeholder="请输入手机号" class="layui-input" autocomplete="off">
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">用户组</label>
                            <div class="layui-input-block">
                                <select id="group_id" name="group_id" lay-search="">
                                    <option value="">请选择用户组</option>
                                </select>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">性别</label>
                            <div class="layui-input-block">
                                <select id="gender" name="gender">
                                    <option value="0">未知</option>
                                    <option value="1">男</option>
                                    <option value="2">女</option>
                                </select>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">签名</label>
                            <div class="layui-input-block">
                                <textarea id="signature" name="signature" placeholder="请输入签名" class="layui-textarea"></textarea>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">状态</label>
                            <div class="layui-input-block">
                                <select id="status" name="status">
                                    <option value="1">正常</option>
                                    <option value="0">禁用</option>
                                </select>
                            </div>
                        </div>
                        <!-- 扩展字段区域，由JS动态渲染 -->
                        <div id="ext-fields-container"></div>
                    </div>
                </div>
            </div>
        </div>
        <div class="bottom">
            <div class="button-container">
                <button type="submit" class="layui-btn layui-btn-normal layui-btn-sm" lay-submit lay-filter="save">
                    <i class="layui-icon layui-icon-ok"></i> 提交
                </button>
                <button type="reset" class="layui-btn layui-btn-primary layui-btn-sm">
                    <i class="layui-icon layui-icon-refresh"></i> 清空
                </button>
            </div>
        </div>
    </form>

    <script src="{{ asset('CmsProUi/component/layui/layui.js') }}"></script>
    <script src="{{ asset('CmsProUi/component/pear/pear.js') }}"></script>
    <script>
        layui.use(['form', 'jquery', 'formSelects'], function() {
            var form = layui.form;
            var $ = layui.jquery;
            var formSelects = layui.formSelects;

            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
                },
                statusCode: {
                    401: function() {
                        layer.msg('登录已过期，请重新登录', {icon: 2, time: 1500}, function() {
                            window.location.href = '/admin/login?redirect=' + encodeURIComponent(window.location.pathname + window.location.search);
                        });
                    }
                }
            });

            var editId = new URLSearchParams(window.location.search).get('id');
            var isEdit = !!editId;
            var extFieldsDef = []; // 扩展字段定义缓存

            if (isEdit) {
                $('#password-item').find('input').removeAttr('lay-verify');
                $('#password-item').find('.layui-form-label').append('<span style="color:#999;font-size:12px;">(留空则不修改)</span>');
            } else {
                $('#password').attr('lay-verify', 'required');
                $('#password').attr('lay-reqText', '密码不能为空');
            }

            // 暂存扩展字段值，用于协调 loadExtFields 与 loadUserData 的异步顺序
            // 当 loadUserData 先返回但 extFieldsDef 尚未加载完成时，先暂存；等 loadExtFields 完成后使用
            var pendingExtValues = null;

            // 加载扩展字段定义并渲染
            function loadExtFields() {
                $.ajax({
                    url: '/api/admin/user-ext-fields',
                    type: 'GET', dataType: 'json',
                    success: function(res) {
                        if (res.code === 0 && res.data) {
                            extFieldsDef = res.data.filter(function(f) { return f.status === 1 || f.status === '1'; });
                            // 如果 loadUserData 已先返回并暂存了扩展值，使用暂存值渲染；否则渲染空表单
                            renderExtFields(pendingExtValues || {});
                            pendingExtValues = null;
                        }
                    }
                });
            }

            // 渲染版本号，用于避免重复渲染时的 AJAX 竞态
            var renderVersion = 0;

            // 根据字段定义渲染表单项
            function renderExtFields(values) {
                renderVersion++;
                var currentVersion = renderVersion;
                var html = '';
                // 先收集需要动态拉取选项的 select 字段
                var sourceFields = [];
                for (var i = 0; i < extFieldsDef.length; i++) {
                    var f = extFieldsDef[i];
                    var val = values[f.field_name] || '';
                    html += '<div class="layui-form-item">';
                    html += '<label class="layui-form-label">' + f.field_label + '</label>';
                    html += '<div class="layui-input-block">';
                    if (f.field_type === 'select') {
                        var opts = f.field_options || [];
                        var isSource = opts && typeof opts === 'object' && opts.source;
                        var isMultiple = opts && typeof opts === 'object' && opts.multiple === true;
                        if (isMultiple) {
                            // 多选：使用 xm-select 下拉多选组件
                            // 动态数据源先渲染为普通 select，AJAX 回调中填充 option 后再初始化 xm-select
                            if (isSource) {
                                html += '<select name="ext_' + f.field_name + '" id="ext_sel_' + f.field_name + '">';
                                html += '<option value="">加载中...</option>';
                                html += '</select>';
                                sourceFields.push({ name: f.field_name, source: opts.source, value: val, multiple: true });
                            } else {
                                // 静态选项：直接渲染带 xm-select 属性的 select
                                html += '<select name="ext_' + f.field_name + '" xm-select="ext_' + f.field_name + '" xm-select-search>';
                                var optList = opts.options || opts;
                                for (var j = 0; j < optList.length; j++) {
                                    var selectedAttr = (Array.isArray(val) && val.indexOf(String(optList[j].value)) !== -1) ? ' selected' : '';
                                    html += '<option value="' + optList[j].value + '"' + selectedAttr + '>' + optList[j].label + '</option>';
                                }
                                html += '</select>';
                            }
                        } else {
                            // 单选
                            html += '<select name="ext_' + f.field_name + '"><option value="">请选择</option>';
                            if (isSource) {
                                sourceFields.push({ name: f.field_name, source: opts.source, value: val, multiple: false });
                            } else {
                                for (var j = 0; j < opts.length; j++) {
                                    var sel = opts[j].value === val ? ' selected' : '';
                                    html += '<option value="' + opts[j].value + '"' + sel + '>' + opts[j].label + '</option>';
                                }
                            }
                            html += '</select>';
                        }
                    } else if (f.field_type === 'textarea') {
                        html += '<textarea name="ext_' + f.field_name + '" placeholder="请输入' + f.field_label + '" class="layui-textarea">' + val + '</textarea>';
                    } else if (f.field_type === 'switch') {
                        var chk = val === '1' || val === 1 ? ' checked' : '';
                        html += '<input type="checkbox" name="ext_' + f.field_name + '" lay-skin="switch" lay-text="是|否" value="1"' + chk + '>';
                    } else if (f.field_type === 'date') {
                        html += '<input type="text" name="ext_' + f.field_name + '" id="ext_date_' + f.field_name + '" placeholder="请选择' + f.field_label + '" class="layui-input" value="' + val + '">';
                    } else if (f.field_type === 'number') {
                        html += '<input type="number" name="ext_' + f.field_name + '" placeholder="请输入' + f.field_label + '" class="layui-input" value="' + val + '" autocomplete="off">';
                    } else if (f.field_type === 'json') {
                        html += '<textarea name="ext_' + f.field_name + '" placeholder="请输入' + f.field_label + '（JSON格式）" class="layui-textarea">' + val + '</textarea>';
                    } else {
                        html += '<input type="text" name="ext_' + f.field_name + '" placeholder="请输入' + f.field_label + '" class="layui-input" value="' + val + '" autocomplete="off">';
                    }
                    html += '</div></div>';
                }
                $('#ext-fields-container').html(html);
                // 渲染日期选择器
                for (var i = 0; i < extFieldsDef.length; i++) {
                    if (extFieldsDef[i].field_type === 'date') {
                        layui.laydate.render({ elem: '#ext_date_' + extFieldsDef[i].field_name });
                    }
                }
                form.render();
                // 渲染静态选项的 xm-select 多选组件（动态数据源的由 AJAX 回调渲染）
                var xmSelectFields = extFieldsDef.filter(function(f) {
                    return f.field_type === 'select' && f.field_options && f.field_options.multiple === true;
                });
                xmSelectFields.forEach(function(f) {
                    var opts = f.field_options || {};
                    var isSource = opts && typeof opts === 'object' && opts.source;
                    if (!isSource) {
                        var xmSelectId = 'ext_' + f.field_name;
                        formSelects.render(xmSelectId, {
                            isSearch: true,
                        });
                    }
                });
                // 动态拉取 select 选项（带版本号检查，避免过期请求覆盖）
                sourceFields.forEach(function(item) {
                    $.ajax({
                        url: item.source.url, type: 'GET', dataType: 'json',
                        success: function(res) {
                            if (currentVersion !== renderVersion) return;
                            if (res.code === 0 && res.data) {
                                var list = Array.isArray(res.data) ? res.data : (res.data.items || []);
                                if (item.multiple) {
                                    // 多选动态数据源：先填充 option，再添加 xm-select 属性，最后初始化
                                    var xmSelectId = 'ext_' + item.name;
                                    var $sel = $('#ext_sel_' + item.name);
                                    // 构建 option HTML，带 selected 属性回填选中值
                                    var optionsHtml = '<option value=""></option>';
                                    for (var k = 0; k < list.length; k++) {
                                        var optVal = list[k][item.source.value_key];
                                        var optLabel = list[k][item.source.label_key];
                                        var isSelected = (Array.isArray(item.value) && item.value.indexOf(String(optVal)) !== -1);
                                        optionsHtml += '<option value="' + optVal + '"' + (isSelected ? ' selected' : '') + '>' + optLabel + '</option>';
                                    }
                                    $sel.html(optionsHtml);
                                    // 添加 xm-select 属性
                                    $sel.attr('xm-select', xmSelectId);
                                    $sel.attr('xm-select-search', '');
                                    // 移除 Layui 对该 select 的渲染（如有）
                                    $sel.next('.layui-form-select').remove();
                                    // 初始化 xm-select
                                    formSelects.render(xmSelectId, {
                                        isSearch: true,
                                    });
                                } else {
                                    var $sel = $('select[name="ext_' + item.name + '"]');
                                    var optionsHtml = '<option value="">请选择</option>';
                                    for (var k = 0; k < list.length; k++) {
                                        var optVal = list[k][item.source.value_key];
                                        var optLabel = list[k][item.source.label_key];
                                        var sel = String(optVal) === String(item.value) ? ' selected' : '';
                                        optionsHtml += '<option value="' + optVal + '"' + sel + '>' + optLabel + '</option>';
                                    }
                                    $sel.html(optionsHtml);
                                    form.render('select');
                                }
                            }
                        }
                    });
                });
            }

            loadExtFields();

            // 加载用户组选项
            $.ajax({
                url: '/api/admin/user-groups/all',
                type: 'GET',
                dataType: 'json',
                success: function(res) {
                    if (res.code === 0 && res.data) {
                        var defaultGroupId = null;
                        var options = '<option value="">请选择用户组</option>';
                        res.data.forEach(function(item) {
                            var selected = '';
                            // 新增模式下，自动选中默认用户组
                            if (!isEdit && item.is_default == 1) {
                                selected = ' selected';
                                defaultGroupId = item.id;
                            }
                            options += '<option value="' + item.id + '"' + selected + '>' + item.name + '</option>';
                        });
                        $('#group_id').html(options);

                        if (isEdit) {
                            loadUserData();
                        } else if (defaultGroupId) {
                            // 新增模式下设置默认值
                            $('#group_id').val(defaultGroupId);
                        }

                        form.render('select');
                    }
                }
            });

            function loadUserData() {
                $.ajax({
                    url: '/api/admin/front-users/' + editId,
                    type: 'GET',
                    dataType: 'json',
                    success: function(res) {
                        if (res.code === 0 && res.data) {
                            var d = res.data;
                            $('#id').val(d.id);
                            $('#username').val(d.username);
                            $('#nickname').val(d.nickname || '');
                            $('#email').val(d.email || '');
                            $('#phone').val(d.phone || '');
                            $('#group_id').val(d.group_id || '');
                            $('#gender').val(d.gender !== undefined ? d.gender : '0');
                            $('#signature').val(d.signature || '');
                            $('#status').val(d.status);
                            form.render();
                            // 回填扩展字段
                            if (d.ext_fields) {
                                // 若字段定义已加载完成，直接渲染；否则暂存等 loadExtFields 完成后渲染
                                if (extFieldsDef.length > 0) {
                                    renderExtFields(d.ext_fields);
                                } else {
                                    pendingExtValues = d.ext_fields;
                                }
                            }
                        }
                    }
                });
            }

            form.on('submit(save)', function(data) {
                var url = isEdit ? '/api/admin/front-users/' + editId : '/api/admin/front-users';
                var method = isEdit ? 'PUT' : 'POST';

                if (isEdit && !data.field.password) {
                    delete data.field.password;
                }

                // 收集扩展字段数据
                var extFields = {};
                for (var i = 0; i < extFieldsDef.length; i++) {
                    var f = extFieldsDef[i];
                    var fname = f.field_name;
                    var key = 'ext_' + fname;
                    var opts = f.field_options || {};
                    var isMultipleSelect = (f.field_type === 'select' && typeof opts === 'object' && opts.multiple === true);
                    if (isMultipleSelect) {
                        // 多选 select：从 xm-select 获取选中值（'val' 返回纯值数组，避免拿到对象数组）
                        var xmSelectId = 'ext_' + fname;
                        extFields[fname] = formSelects.value(xmSelectId, 'val').map(function(v){ return String(v); });
                    } else if (f.field_type === 'switch') {
                        extFields[fname] = data.field[key] ? '1' : '0';
                        delete data.field[key];
                    } else if (data.field[key] !== undefined) {
                        extFields[fname] = data.field[key];
                        delete data.field[key];
                    }
                }
                data.field.ext_fields = extFields;

                $.ajax({
                    url: url,
                    type: method,
                    dataType: 'json',
                    contentType: 'application/json',
                    data: JSON.stringify(data.field),
                    success: function(res) {
                        if (res.code === 0) {
                            layer.msg(isEdit ? '编辑成功' : '新增成功', { icon: 1, time: 1000 }, function() {
                            var index = parent.layer.getFrameIndex(window.name);
                            parent.layer.close(index);
                            parent.layui.table.reload('user-table');
                        });
                        } else {
                            layer.msg(res.message || '操作失败', { icon: 2, time: 1500 });
                        }
                    },
                    error: function() {
                        layer.msg('请求失败', { icon: 2, time: 1500 });
                    }
                });
                return false;
            });
        });
    </script>
</body>
</html>
