// 客户回访登记系统 - JavaScript应用逻辑 (SQLite版本)

const app = {
    // 当前状态
    currentUser: null,
    currentPage: {
        customers: 1,
        pageSize: 10
    },
    customerPhotos: [],
    productPhotos: [],
    chart: null,
    db: null,
    dbReady: false,
    
    // 跨标签页通信
    broadcastChannel: null,

    // 地图数据
    chinaMapPaths: {},
    henanMapPaths: {},
    henanChart: null, // 河南地图 ECharts 实例

    // 权限配置
    PERMISSIONS: {
        customer: {
            add: '添加客户',
            edit: '编辑客户',
            delete: '删除客户',
            view: '查看客户'
        },
        script: {
            add: '添加话术',
            edit: '编辑话术',
            delete: '删除话术'
        },
        product: {
            add: '添加产品',
            edit: '编辑产品',
            delete: '删除产品'
        },
        data: {
            export: '导出数据',
            import: '导入数据',
            clear: '清空数据'
        },
        user: {
            manage: '用户管理'
        }
    },

    // 省市数据
    provinceCityData: {
        "北京市": ["北京市"],
        "天津市": ["天津市"],
        "河北省": ["石家庄市", "唐山市", "秦皇岛市", "邯郸市", "邢台市", "保定市", "张家口市", "承德市", "沧州市", "廊坊市", "衡水市"],
        "山西省": ["太原市", "大同市", "阳泉市", "长治市", "晋城市", "朔州市", "晋中市", "运城市", "忻州市", "临汾市", "吕梁市"],
        "内蒙古自治区": ["呼和浩特市", "包头市", "乌海市", "赤峰市", "通辽市", "鄂尔多斯市", "呼伦贝尔市", "巴彦淖尔市", "乌兰察布市", "兴安盟", "锡林郭勒盟", "阿拉善盟"],
        "辽宁省": ["沈阳市", "大连市", "鞍山市", "抚顺市", "本溪市", "丹东市", "锦州市", "营口市", "阜新市", "辽阳市", "盘锦市", "铁岭市", "朝阳市", "葫芦岛市"],
        "吉林省": ["长春市", "吉林市", "四平市", "辽源市", "通化市", "白山市", "松原市", "白城市", "延边朝鲜族自治州"],
        "黑龙江省": ["哈尔滨市", "齐齐哈尔市", "鸡西市", "鹤岗市", "双鸭山市", "大庆市", "伊春市", "佳木斯市", "七台河市", "牡丹江市", "黑河市", "绥化市", "大兴安岭地区"],
        "上海市": ["上海市"],
        "江苏省": ["南京市", "无锡市", "徐州市", "常州市", "苏州市", "南通市", "连云港市", "淮安市", "盐城市", "扬州市", "镇江市", "泰州市", "宿迁市"],
        "浙江省": ["杭州市", "宁波市", "温州市", "嘉兴市", "湖州市", "绍兴市", "金华市", "衢州市", "舟山市", "台州市", "丽水市"],
        "安徽省": ["合肥市", "芜湖市", "蚌埠市", "淮南市", "马鞍山市", "淮北市", "铜陵市", "安庆市", "黄山市", "滁州市", "阜阳市", "宿州市", "六安市", "亳州市", "池州市", "宣城市"],
        "福建省": ["福州市", "厦门市", "莆田市", "三明市", "泉州市", "漳州市", "南平市", "龙岩市", "宁德市"],
        "江西省": ["南昌市", "景德镇市", "萍乡市", "九江市", "新余市", "鹰潭市", "赣州市", "吉安市", "宜春市", "抚州市", "上饶市"],
        "山东省": ["济南市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市", "威海市", "日照市", "莱芜市", "临沂市", "德州市", "聊城市", "滨州市", "菏泽市"],
        "河南省": ["郑州市", "开封市", "洛阳市", "平顶山市", "安阳市", "鹤壁市", "新乡市", "焦作市", "濮阳市", "许昌市", "漯河市", "三门峡市", "南阳市", "商丘市", "信阳市", "周口市", "驻马店市", "济源市"],
        "湖北省": ["武汉市", "黄石市", "十堰市", "宜昌市", "襄阳市", "鄂州市", "荆门市", "孝感市", "荆州市", "黄冈市", "咸宁市", "随州市", "恩施土家族苗族自治州", "仙桃市", "潜江市", "天门市", "神农架林区"],
        "湖南省": ["长沙市", "株洲市", "湘潭市", "衡阳市", "邵阳市", "岳阳市", "常德市", "张家界市", "益阳市", "郴州市", "永州市", "怀化市", "娄底市", "湘西土家族苗族自治州"],
        "广东省": ["广州市", "韶关市", "深圳市", "珠海市", "汕头市", "佛山市", "江门市", "湛江市", "茂名市", "肇庆市", "惠州市", "梅州市", "汕尾市", "河源市", "阳江市", "清远市", "东莞市", "中山市", "潮州市", "揭阳市", "云浮市"],
        "广西壮族自治区": ["南宁市", "柳州市", "桂林市", "梧州市", "北海市", "防城港市", "钦州市", "贵港市", "玉林市", "百色市", "贺州市", "河池市", "来宾市", "崇左市"],
        "海南省": ["海口市", "三亚市", "三沙市", "儋州市", "五指山市", "琼海市", "文昌市", "万宁市", "东方市", "定安县", "屯昌县", "澄迈县", "临高县", "白沙黎族自治县", "昌江黎族自治县", "乐东黎族自治县", "陵水黎族自治县", "保亭黎族苗族自治县", "琼中黎族苗族自治县"],
        "重庆市": ["重庆市"],
        "四川省": ["成都市", "自贡市", "攀枝花市", "泸州市", "德阳市", "绵阳市", "广元市", "遂宁市", "内江市", "乐山市", "南充市", "眉山市", "宜宾市", "广安市", "达州市", "雅安市", "巴中市", "资阳市", "阿坝藏族羌族自治州", "甘孜藏族自治州", "凉山彝族自治州"],
        "贵州省": ["贵阳市", "六盘水市", "遵义市", "安顺市", "毕节市", "铜仁市", "黔西南布依族苗族自治州", "黔东南苗族侗族自治州", "黔南布依族苗族自治州"],
        "云南省": ["昆明市", "曲靖市", "玉溪市", "保山市", "昭通市", "丽江市", "普洱市", "临沧市", "楚雄彝族自治州", "红河哈尼族彝族自治州", "文山壮族苗族自治州", "西双版纳傣族自治州", "大理白族自治州", "德宏傣族景颇族自治州", "怒江傈僳族自治州", "迪庆藏族自治州"],
        "西藏自治区": ["拉萨市", "日喀则市", "昌都市", "林芝市", "山南市", "那曲市", "阿里地区"],
        "陕西省": ["西安市", "铜川市", "宝鸡市", "咸阳市", "渭南市", "延安市", "汉中市", "榆林市", "安康市", "商洛市"],
        "甘肃省": ["兰州市", "嘉峪关市", "金昌市", "白银市", "天水市", "武威市", "张掖市", "平凉市", "酒泉市", "庆阳市", "定西市", "陇南市", "临夏回族自治州", "甘南藏族自治州"],
        "青海省": ["西宁市", "海东市", "海北藏族自治州", "黄南藏族自治州", "海南藏族自治州", "果洛藏族自治州", "玉树藏族自治州", "海西蒙古族藏族自治州"],
        "宁夏回族自治区": ["银川市", "石嘴山市", "吴忠市", "固原市", "中卫市"],
        "新疆维吾尔自治区": ["乌鲁木齐市", "克拉玛依市", "吐鲁番市", "哈密市", "昌吉回族自治州", "博尔塔拉蒙古自治州", "巴音郭楞蒙古自治州", "阿克苏地区", "克孜勒苏柯尔克孜自治州", "喀什地区", "和田地区", "伊犁哈萨克自治州", "塔城地区", "阿勒泰地区", "石河子市", "阿拉尔市", "图木舒克市", "五家渠市", "北屯市", "铁门关市", "双河市", "可克达拉市", "昆玉市", "胡杨河市", "新星市"],
        "台湾省": ["台北市", "新北市", "桃园市", "台中市", "台南市", "高雄市", "基隆市", "新竹市", "嘉义市", "新竹县", "苗栗县", "彰化县", "南投县", "云林县", "嘉义县", "屏东县", "宜兰县", "花莲县", "台东县", "澎湖县", "金门县", "连江县"],
        "香港特别行政区": ["香港特别行政区"],
        "澳门特别行政区": ["澳门特别行政区"]
    },

    // 初始化
    async init() {
        this.initDeviceDetection();
        this.initDarkMode();
        this.initEventListeners();
        this.initBroadcastChannel();
        await this.loadMapData();
        await this.initDatabase();
    },

    // ==================== 深色主题 ====================
    initDarkMode() {
        const isDark = localStorage.getItem('crv_dark_mode') === 'true';
        if (isDark) {
            document.body.classList.add('dark-theme');
        }
        // 等 DOM 加载完毕后同步开关状态
        window.addEventListener('load', () => this.syncDarkModeToggle());
    },

    syncDarkModeToggle() {
        const isDark = document.body.classList.contains('dark-theme');
        const checkbox = document.getElementById('darkModeToggle');
        const track = document.getElementById('themeToggleTrack');
        const thumb = document.getElementById('themeToggleThumb');
        const textLeft = document.getElementById('themeToggleText');
        const textRight = document.getElementById('themeToggleTextRight');
        
        if (checkbox) checkbox.checked = isDark;
        if (track) track.style.background = isDark ? '#4F46E5' : '#D1D5DB';
        if (thumb) thumb.style.transform = isDark ? 'translateX(22px)' : 'translateX(0)';
        if (textLeft) textLeft.style.color = isDark ? '#9CA3AF' : '#6b7280';
        if (textRight) textRight.style.color = isDark ? '#9CA3AF' : '#6b7280';
    },

    toggleDarkMode(enabled) {
        if (enabled) {
            document.body.classList.add('dark-theme');
            localStorage.setItem('crv_dark_mode', 'true');
        } else {
            document.body.classList.remove('dark-theme');
            localStorage.setItem('crv_dark_mode', 'false');
        }
        this.syncDarkModeToggle();
        this.showToast(enabled ? '已切换到深色主题' : '已切换到浅色主题', 'success');
    },


    
    // 初始化跨标签页通信
    initBroadcastChannel() {
        try {
            // 创建 BroadcastChannel 用于跨标签页通信
            this.broadcastChannel = new BroadcastChannel('customer_return_visit_sync');
            this.broadcastChannel.onmessage = (event) => {
                const { type, data, table } = event.data;
                console.log('收到同步消息:', type, table);
                
                switch (type) {
                    case 'DATA_CHANGED':
                        // 数据变更时刷新相关页面
                        this.handleDataSync(table, data);
                        break;
                    case 'CUSTOMER_UPDATED':
                        // 客户数据更新
                        this.refreshCustomerData();
                        break;
                    case 'SETTINGS_UPDATED':
                        // 设置更新（如经营范围）
                        this.refreshSettingsData();
                        break;
                }
            };
            console.log('BroadcastChannel 初始化成功');
        } catch (err) {
            console.warn('BroadcastChannel 不支持或初始化失败:', err);
            // 降级方案：使用 localStorage 监听
            this.initStorageSync();
        }
    },
    
    // 降级方案：使用 localStorage 实现跨标签页同步
    initStorageSync() {
        window.addEventListener('storage', (event) => {
            if (event.key === 'crv_sync_event') {
                try {
                    const syncData = JSON.parse(event.newValue);
                    console.log('收到 storage 同步消息:', syncData);
                    this.handleDataSync(syncData.table, syncData.data);
                } catch (err) {
                    console.error('解析同步数据失败:', err);
                }
            }
        });
        console.log('Storage 同步方案初始化成功');
    },
    
    // 发送数据变更通知
    notifyDataChange(table, data = null) {
        const message = { type: 'DATA_CHANGED', table, data, timestamp: Date.now() };
        
        // 使用 BroadcastChannel
        if (this.broadcastChannel) {
            this.broadcastChannel.postMessage(message);
        }
        
        // 降级方案：使用 localStorage
        try {
            localStorage.setItem('crv_sync_event', JSON.stringify(message));
            // 立即清除，避免影响下次同步
            setTimeout(() => localStorage.removeItem('crv_sync_event'), 100);
        } catch (err) {
            console.warn('localStorage 同步失败:', err);
        }
    },
    
    // 处理数据同步
    async handleDataSync(table, data) {
        console.log('处理数据同步:', table);
        
        switch (table) {
            case 'customers':
                await this.refreshCustomerData();
                break;
            case 'settings':
                await this.refreshSettingsData();
                break;
            case 'industry_schemes':
                await this.refreshIndustrySchemes();
                break;
            case 'products':
                await this.refreshProducts();
                break;
            case 'visit_records':
                await this.refreshVisitRecords();
                break;
            case 'scripts':
                await this.refreshScripts();
                break;
        }
    },
    
    // 刷新客户数据
    async refreshCustomerData() {
        // 如果在客户列表页面，刷新表格
        if (document.getElementById('customerListSection')?.classList.contains('active')) {
            await this.loadCustomers();
            this.showToast('客户数据已更新', 'info');
        }
        // 如果在首页，刷新统计数据
        if (document.getElementById('dashboardSection')?.classList.contains('active')) {
            await this.loadDashboard();
        }
    },
    
    // 刷新设置数据（经营范围等）
    async refreshSettingsData() {
        // 刷新经营范围选项
        await this.loadBusinessScopeCheckboxes();
        // 如果在分类管理页面，刷新显示
        if (document.getElementById('classifySection')?.classList.contains('active')) {
            await this.loadClassify();
        }
        this.showToast('设置数据已更新', 'info');
    },
    
    // 刷新行业方案
    async refreshIndustrySchemes() {
        if (document.getElementById('productSection')?.classList.contains('active')) {
            await this.renderIndustrySchemeList();
            this.showToast('行业方案已更新', 'info');
        }
    },
    
    // 刷新产品数据
    async refreshProducts() {
        if (document.getElementById('productSection')?.classList.contains('active')) {
            await this.renderProductGrid();
        }
    },
    
    // 刷新回访记录
    async refreshVisitRecords() {
        // 刷新回访提醒等
        await this.updateNotificationBadge();
        if (document.getElementById('dashboardSection')?.classList.contains('active')) {
            await this.loadDashboard();
        }
    },
    
    // 刷新话术数据
    async refreshScripts() {
        if (document.getElementById('scriptSection')?.classList.contains('active')) {
            await this.loadScripts();
        }
    },

    // 加载地图数据
    async loadMapData() {
        try {
            // 使用内嵌全局变量加载中国地图数据，避免file://协议下fetch失败
            this.chinaMapPaths = {};
            if (typeof CHINA_MAP_DATA !== 'undefined') {
                CHINA_MAP_DATA.forEach(item => {
                    this.chinaMapPaths[item.name] = item.svg;
                });
            }

            // 使用内嵌全局变量加载河南地图数据
            this.henanMapPaths = {};
            if (typeof HENAN_CITIES_MAP_DATA !== 'undefined') {
                HENAN_CITIES_MAP_DATA.forEach(item => {
                    this.henanMapPaths[item.name] = item.svg;
                });
            }

            console.log('地图数据加载完成');
            console.log('中国地图省份数量:', Object.keys(this.chinaMapPaths).length);
            console.log('河南地图城市数量:', Object.keys(this.henanMapPaths).length);
        } catch (error) {
            console.error('地图数据加载失败:', error);
            console.error('错误详情:', error.message);
            this.chinaMapPaths = {};
            this.henanMapPaths = {};
        }
    },

    // 设备检测
    initDeviceDetection() {
        this.isMobile = window.innerWidth <= 768 || /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
        
        // 监听窗口大小变化
        window.addEventListener('resize', () => {
            const wasMobile = this.isMobile;
            this.isMobile = window.innerWidth <= 768;
            if (wasMobile !== this.isMobile) {
                this.onDeviceChange();
            }
        });

        // 初始设置
        this.updateUIForDevice();
    },

    // 设备变化时更新UI
    onDeviceChange() {
        this.updateUIForDevice();
        // 重新渲染当前页面
        const currentPage = this.currentPage || 'dashboard';
        this.navigateTo(currentPage);
    },

    // 根据设备更新UI
    updateUIForDevice() {
        const mobileHeader = document.getElementById('mobileHeader');
        const mobileNav = document.getElementById('mobileNav');
        const topHeader = document.querySelector('.top-header');
        const sidebar = document.getElementById('sidebar');

        if (this.isMobile) {
            if (mobileHeader) mobileHeader.style.display = 'flex';
            if (mobileNav) mobileNav.style.display = 'flex';
            if (topHeader) topHeader.style.display = 'none';
            if (sidebar) sidebar.style.display = 'none';
            document.body.classList.add('mobile-view');
        } else {
            if (mobileHeader) mobileHeader.style.display = 'none';
            if (mobileNav) mobileNav.style.display = 'none';
            if (topHeader) topHeader.style.display = 'flex';
            if (sidebar) sidebar.style.display = 'flex';
            document.body.classList.remove('mobile-view');
        }
    },

    // 初始化SQLite数据库
    async initDatabase() {
        return new Promise((resolve, reject) => {
            const dbName = 'CustomerReturnVisitDB';
            
            // 尝试打开已存在的数据库（版本10：添加行业方案表）
            const request = indexedDB.open(dbName, 10);
            
            request.onerror = () => {
                console.error('数据库打开失败:', request.error);
                reject(request.error);
            };
            
            request.onsuccess = (event) => {
                this.db = event.target.result;
                this.dbReady = true;
                console.log('数据库连接成功');
                this.initData().then(() => {
                    this.initLogin();
                    resolve();
                }).catch(err => {
                    console.error('初始化数据失败:', err);
                    // 即使数据初始化失败，也尝试初始化登录
                    this.initLogin();
                    resolve();
                });
            };
            
            request.onupgradeneeded = (event) => {
                const db = event.target.result;
                
                // 创建用户表
                if (!db.objectStoreNames.contains('users')) {
                    const userStore = db.createObjectStore('users', { keyPath: 'id' });
                    userStore.createIndex('username', 'username', { unique: true });
                }
                
                // 创建客户表
                if (!db.objectStoreNames.contains('customers')) {
                    const customerStore = db.createObjectStore('customers', { keyPath: 'id' });
                    customerStore.createIndex('ownerUsers', 'ownerUsers', { multiEntry: true });
                }
                
                // 创建话术表
                if (!db.objectStoreNames.contains('scripts')) {
                    db.createObjectStore('scripts', { keyPath: 'id' });
                }
                
                // 创建产品表
                if (!db.objectStoreNames.contains('products')) {
                    db.createObjectStore('products', { keyPath: 'id' });
                }
                
                // 创建回访记录表
                if (!db.objectStoreNames.contains('visit_records')) {
                    const recordStore = db.createObjectStore('visit_records', { keyPath: 'id' });
                    recordStore.createIndex('customerId', 'customerId', { unique: false });
                }
                
                // 创建设置表
                if (!db.objectStoreNames.contains('settings')) {
                    db.createObjectStore('settings', { keyPath: 'id' });
                }
                
                // 创建权限组表
                if (!db.objectStoreNames.contains('permission_groups')) {
                    db.createObjectStore('permission_groups', { keyPath: 'id' });
                }
                
                // 创建行业方案表
                if (!db.objectStoreNames.contains('industry_schemes')) {
                    db.createObjectStore('industry_schemes', { keyPath: 'id' });
                }
                
                console.log('数据库表创建完成');
            };
        });
    },

    // 数据库操作辅助方法
    dbGetAll(storeName) {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }
            const transaction = this.db.transaction(storeName, 'readonly');
            const store = transaction.objectStore(storeName);
            const request = store.getAll();
            request.onsuccess = () => resolve(request.result || []);
            request.onerror = () => {
                console.error('数据库读取失败:', storeName, request.error);
                reject(request.error);
            };
        });
    },

    dbGet(storeName, key) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction(storeName, 'readonly');
            const store = transaction.objectStore(storeName);
            const request = store.get(key);
            request.onsuccess = () => resolve(request.result);
            request.onerror = () => reject(request.error);
        });
    },

    dbPut(storeName, data) {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }
            const transaction = this.db.transaction(storeName, 'readwrite');
            const store = transaction.objectStore(storeName);
            const request = store.put(data);
            request.onsuccess = () => {
                // 数据变更后通知其他标签页
                this.notifyDataChange(storeName, data);
                resolve(request.result);
            };
            request.onerror = () => {
                console.error('数据库写入失败:', request.error);
                reject(request.error);
            };
        });
    },

    dbDelete(storeName, key) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction(storeName, 'readwrite');
            const store = transaction.objectStore(storeName);
            const request = store.delete(key);
            request.onsuccess = () => {
                // 数据删除后通知其他标签页
                this.notifyDataChange(storeName, { deleted: true, key });
                resolve(request.result);
            };
            request.onerror = () => reject(request.error);
        });
    },

    dbClear(storeName) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction(storeName, 'readwrite');
            const store = transaction.objectStore(storeName);
            const request = store.clear();
            request.onsuccess = () => resolve();
            request.onerror = () => reject(request.error);
        });
    },

    // 批量写入（put，有则覆盖，无则新增）
    dbBulkPut(storeName, items) {
        return new Promise((resolve, reject) => {
            if (!this.db || !items || items.length === 0) { resolve(); return; }
            const transaction = this.db.transaction(storeName, 'readwrite');
            const store = transaction.objectStore(storeName);
            let done = 0;
            let hasError = false;
            items.forEach(item => {
                const req = store.put(item);
                req.onsuccess = () => { done++; if (done === items.length && !hasError) resolve(); };
                req.onerror = (e) => { if (!hasError) { hasError = true; reject(e.target.error); } };
            });
            if (items.length === 0) resolve();
        });
    },

    // 密码加密 - SHA-256哈希（带兼容性回退）
    async hashPassword(password) {
        try {
            // 检查 crypto.subtle 是否可用
            if (typeof crypto !== 'undefined' && crypto.subtle) {
                const encoder = new TextEncoder();
                const data = encoder.encode(password + 'crv_salt_2024');
                const hashBuffer = await crypto.subtle.digest('SHA-256', data);
                const hashArray = Array.from(new Uint8Array(hashBuffer));
                return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
            }
        } catch (e) {
            console.warn('SHA-256哈希失败，使用简单哈希:', e);
        }
        // 回退：使用简单字符串哈希
        let hash = 0;
        const str = password + 'crv_salt_2024';
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash;
        }
        return 'simple_' + Math.abs(hash).toString(16);
    },

    // 验证密码（兼容旧明文密码）
    async verifyPassword(password, storedHash) {
        // 先尝试哈希比较
        const hashed = await this.hashPassword(password);
        if (hashed === storedHash) return true;
        // 兼容旧明文密码
        return password === storedHash;
    },

    // 初始化默认数据
    async initData() {
        const users = await this.dbGetAll('users');
        
        // 初始化权限组
        const groups = await this.dbGetAll('permission_groups');
        if (groups.length === 0) {
            const defaultGroups = [
                {
                    id: this.generateId(),
                    name: '管理员组',
                    code: 'admin_group',
                    description: '拥有所有权限',
                    permissions: ['customer.add', 'customer.edit', 'customer.delete', 'customer.view', 'script.add', 'script.edit', 'script.delete', 'product.add', 'product.edit', 'product.delete', 'data.export', 'data.import', 'data.clear', 'user.manage'],
                    isSystem: true,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '经理组',
                    code: 'manager_group',
                    description: '可管理客户和查看数据',
                    permissions: ['customer.add', 'customer.edit', 'customer.view', 'customer.delete', 'script.add', 'script.edit', 'script.delete', 'product.add', 'product.edit', 'product.delete', 'data.export'],
                    isSystem: false,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '员工组',
                    code: 'staff_group',
                    description: '基本操作权限',
                    permissions: ['customer.add', 'customer.edit', 'customer.view', 'script.add', 'script.edit', 'product.view'],
                    isSystem: false,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '只读组',
                    code: 'readonly_group',
                    description: '仅可查看数据',
                    permissions: ['customer.view', 'script.view'],
                    isSystem: false,
                    createdAt: new Date().toISOString()
                }
            ];
            for (const group of defaultGroups) {
                await this.dbPut('permission_groups', group);
            }
        }

        // 初始化用户 - 确保admin用户存在且密码正确
        try {
            let adminUser = users.find(u => u.username === 'admin');
            const adminHashedPwd = await this.hashPassword('admin123');
            if (adminUser) {
                // 强制重置admin密码为admin123的哈希值（解决密码不一致问题）
                adminUser.password = adminHashedPwd;
                adminUser.status = 'active';
                await this.dbPut('users', adminUser);
                console.log('Admin用户密码已重置为admin123');
            } else {
                // 创建新的admin用户（哈希密码）
                adminUser = {
                    id: this.generateId(),
                    username: 'admin',
                    password: adminHashedPwd,
                    realName: '系统管理员',
                    role: 'admin',
                    status: 'active',
                    createdAt: new Date().toISOString()
                };
                await this.dbPut('users', adminUser);
                console.log('创建新的Admin用户');
            }
        } catch (err) {
            console.error('初始化admin用户失败:', err);
        }

        // 初始化默认话术（每阶段10条，共60条）
        const scripts = await this.dbGetAll('scripts');
        if (scripts.length === 0) {
            const defaultScripts = [
                // 初次接触阶段（10条）
                { stage: '初次接触', title: '开场白', content: '您好，我是XX公司的XX，首先感谢您抽出时间接听我们的电话。之前我们给您发送过一份产品资料，不知道您有没有收到？', scenario: '首次电话联系' },
                { stage: '初次接触', title: '自我介绍', content: '您好，我是XX公司客户经理XX，我们专注于为XX行业提供优质的XX产品/服务。今天打电话是想和您沟通一下相关需求。', scenario: '自我介绍' },
                { stage: '初次接触', title: '说明来意', content: '您好，是这样的，我们公司最近推出了一款针对XX行业的新产品/服务，觉得非常适合您这边，所以想和您介绍一下。', scenario: '说明来意' },
                { stage: '初次接触', title: '引起兴趣', content: '不知道您最近是否有采购XX产品的计划？我们这边有一个非常不错的方案，可能对您帮助很大。', scenario: '引起兴趣' },
                { stage: '初次接触', title: '预约面谈', content: '为了更好地了解您的需求，我想约您一个时间当面向您介绍我们的产品，您看这周哪天比较方便？', scenario: '预约面谈' },
                { stage: '初次接触', title: '产品价值', content: '我们公司产品的主要优势是XX，已经帮助XX多家企业解决了XX问题，相信对您也会有很大帮助。', scenario: '产品价值' },
                { stage: '初次接触', title: '询问需求', content: '在介绍产品之前，我想先了解一下您目前最关注的是哪些方面？这样我可以针对性地为您推荐最合适的方案。', scenario: '询问需求' },
                { stage: '初次接触', title: '建立信任', content: '我们公司在行业内有XX年的经验，服务过众多知名企业，口碑一直很好。如果您感兴趣，我可以给您发一些成功案例。', scenario: '建立信任' },
                { stage: '初次接触', title: '处理挂断', content: '我理解您现在比较忙，那我稍后给您发一条短信，您先了解一下我们的产品，有任何问题随时联系我，好吗？', scenario: '处理挂断' },
                { stage: '初次接触', title: '持续跟进', content: '非常感谢您的耐心接听，我会把相关资料发到您邮箱，如果您有任何问题，随时给我打电话，谢谢！', scenario: '结束通话' },
                
                // 需求了解阶段（10条）
                { stage: '需求了解', title: '需求挖掘', content: '请问您目前最关注的是产品的哪些方面呢？是价格、质量还是售后服务？我们可以根据您的需求为您推荐最合适的产品方案。', scenario: '了解客户需求' },
                { stage: '需求了解', title: '深入询问', content: '您提到对XX比较关注，能具体说说您在XX方面有什么样的要求吗？这样我能更准确地为您匹配产品。', scenario: '深入询问' },
                { stage: '需求了解', title: '痛点分析', content: '您目前在使用XX产品的过程中，有没有遇到什么问题或者不便？我们这边有专门的解决方案。', scenario: '痛点分析' },
                { stage: '需求了解', title: '预算了解', content: '请问您这边对于XX产品的预算大概是多少呢？我可以根据您的预算为您推荐性价比最高的选择。', scenario: '预算了解' },
                { stage: '需求了解', title: '决策人确认', content: '除了您之外，请问这件事还有谁需要参与决策呢？如果需要，我可以安排统一的时间进行介绍。', scenario: '决策人确认' },
                { stage: '需求了解', title: '采购时间', content: '您计划什么时候开始采购这个产品呢？我们这边可以提前为您准备好方案和报价。', scenario: '采购时间' },
                { stage: '需求了解', title: '竞争对手', content: '您目前有在对比其他供应商吗？方便告诉我主要考虑哪些方面吗？我可以给您做一个详细的对比分析。', scenario: '竞争对手' },
                { stage: '需求了解', title: '用量确认', content: '您这边每月的采购量大概是多少呢？根据用量我们可以给您提供更优惠的价格方案。', scenario: '用量确认' },
                { stage: '需求了解', title: '特殊要求', content: '您这边有没有什么特殊的要求需要我们配合的？比如交货时间、付款方式、售后服务等。', scenario: '特殊要求' },
                { stage: '需求了解', title: '需求总结', content: '好的，根据您刚才的描述，您的需求主要是XX。我这边先整理一下，稍后给您提供一个针对性的方案，好吗？', scenario: '需求总结' },
                
                // 产品介绍阶段（10条）
                { stage: '产品介绍', title: '产品优势', content: '我们的产品具有以下优势：1. 品质有保障；2. 价格合理；3. 售后服务完善；4. 交货及时。如果您有具体需求，我可以为您提供详细的方案。', scenario: '介绍产品特点' },
                { stage: '产品介绍', title: '核心卖点', content: '我们产品最核心的优势是XX，这一点是其他供应商无法比拟的，已经得到了众多客户的验证。', scenario: '核心卖点' },
                { stage: '产品介绍', title: '案例分享', content: '我给您分享一个XX公司的案例，他们之前也有类似的需求，使用了我们的产品后，XX问题得到了很好的解决。', scenario: '案例分享' },
                { stage: '产品介绍', title: '产品演示', content: '为了让您更直观地了解产品，我可以安排一次线上演示，或者发一些产品视频给您看看。', scenario: '产品演示' },
                { stage: '产品介绍', title: '参数详解', content: '这是我们产品的详细参数，您可以看一下。我们在XX方面采用了XX技术，性能非常稳定。', scenario: '参数详解' },
                { stage: '产品介绍', title: '对比优势', content: '和市面上其他产品相比，我们的优势主要体现在XX方面，特别是XX功能，非常适合您这样的企业使用。', scenario: '对比优势' },
                { stage: '产品介绍', title: '适用范围', content: '我们的产品广泛应用于XX行业，特别适合XX规模的企业使用，兼容性非常好。', scenario: '适用范围' },
                { stage: '产品介绍', title: '定制服务', content: '我们也可以根据您的具体需求提供定制服务，包括XX等方面的个性化调整。', scenario: '定制服务' },
                { stage: '产品介绍', title: '供货周期', content: '我们公司的供货周期是XX，正常情况下XX天内可以完成发货，加急的话可以缩短到XX天。', scenario: '供货周期' },
                { stage: '产品介绍', title: '报价说明', content: '这是我们产品的详细报价单，包含XX个规格型号。您看哪个更适合您？我可以为您做一个详细的费用说明。', scenario: '报价说明' },
                
                // 异议处理阶段（10条）
                { stage: '异议处理', title: '价格异议', content: '我理解您对价格的关注。其实我们的产品在同等质量中性价比是非常高的。而且我们提供长期的售后服务，这在后期能为您节省不少维护成本。', scenario: '处理价格异议' },
                { stage: '异议处理', title: '价格谈判', content: '关于价格，我们可以根据您的采购量给予一定的优惠。如果您能确定采购数量，我可以向公司申请更优惠的价格。', scenario: '价格谈判' },
                { stage: '异议处理', title: '质量质疑', content: '我们产品都经过严格的质量检测，有XX认证证书。而且我们提供XX年的质量保证，您可以放心使用。', scenario: '质量质疑' },
                { stage: '异议处理', title: '竞品比较', content: '每个产品都有自己的特点，我很乐意为您分析一下各家的优劣势。但从综合性价比来看，我们的产品是最适合您的。', scenario: '竞品比较' },
                { stage: '异议处理', title: '还在考虑', content: '我完全理解您需要时间考虑。请问您主要在考虑哪些方面呢？或许我可以针对性地为您解答。', scenario: '还在考虑' },
                { stage: '异议处理', title: '需要汇报', content: '这是很正常的，采购决策确实需要多方面的考量。那您方便告诉我还需要和哪些人汇报吗？', scenario: '需要汇报' },
                { stage: '异议处理', title: '已有合作', content: '您目前和XX公司合作，我们可以理解。那您对他们现在的服务满意吗？有没有需要改进的地方？', scenario: '已有合作' },
                { stage: '异议处理', title: '不感兴趣', content: '我完全理解您的立场。不过我们的产品确实帮助很多类似的企业解决了XX问题，也许对您也有所帮助，能否给我几分钟时间介绍一下？', scenario: '不感兴趣' },
                { stage: '异议处理', title: '时间不急', content: '采购时间不急没关系，我们可以先做前期的了解。等您需要的时候，随时联系我，我可以第一时间为您提供服务。', scenario: '时间不急' },
                { stage: '异议处理', title: '再联系您', content: '好的，那我等您消息。在您做决定之前，欢迎随时打电话咨询，我会为您提供全面的支持。', scenario: '再联系您' },
                
                // 促成成交阶段（10条）
                { stage: '促成成交', title: '促成下单', content: '您看如果您对我们的产品满意的话，我们可以先帮您下一个小订单试用，体验一下我们的产品和服务。满意后再大批量采购，您觉得怎么样？', scenario: '促使客户下单' },
                { stage: '促成成交', title: '优惠促成', content: '目前我们公司有XX优惠活动，如果在这个月内下单，可以享受XX折优惠，还可以获赠XX赠品。', scenario: '优惠促成' },
                { stage: '促成成交', title: '限时优惠', content: '这个价格是我们本周的特惠价，下周就要调整了。如果您今天确定的话，我马上帮您申请这个价格。', scenario: '限时优惠' },
                { stage: '促成成交', title: '缺货紧迫', content: '目前这款产品库存比较紧张，很多客户都在订购。如果确定要的话，建议尽快下单，以免影响您的使用。', scenario: '缺货紧迫' },
                { stage: '促成成交', title: '试用促成', content: '我们提供XX天的免费试用期，您不需要承担任何风险。试用期结束后，如果满意再正式合作。', scenario: '试用促成' },
                { stage: '促成成交', title: '合同确认', content: '如果对产品没有其他疑问的话，我们可以先签订采购合同，您看看什么时候方便？', scenario: '合同确认' },
                { stage: '促成成交', title: '付款方式', content: '付款方式很灵活，可以选择XX、XX等方式。我们也可以根据您的具体情况协商合适的付款周期。', scenario: '付款方式' },
                { stage: '促成成交', title: '配送安排', content: '一旦确认订单，我们会在XX天内安排发货。您希望的收货时间是什么时候？我们尽量配合您。', scenario: '配送安排' },
                { stage: '促成成交', title: '售后服务', content: '购买后我们提供XX年的免费售后服务，有任何问题随时联系我们，还会上门进行XX次定期维护。', scenario: '售后服务' },
                { stage: '促成成交', title: '再次确认', content: '好的，那我现在帮您整理一下订单明细：产品XX、数量XX、单价XX、总价XX。请问还有其他需要补充的吗？', scenario: '再次确认' },
                
                // 售后跟进阶段（10条）
                { stage: '售后跟进', title: '满意度调查', content: '您好，请问之前购买的产品使用情况怎么样？有没有什么需要我们协助解决的？您的反馈对我们非常重要。', scenario: '售后服务回访' },
                { stage: '售后跟进', title: '使用回访', content: '您好，产品已经使用一段时间了吧？使用过程中感觉怎么样？有没有遇到什么问题？', scenario: '使用回访' },
                { stage: '售后跟进', title: '产品维护', content: '为了确保产品正常运行，我们建议进行定期维护。我可以安排技术人员上门帮您检查一下。', scenario: '产品维护' },
                { stage: '售后跟进', title: '配件更换', content: '您好，XX配件的更换时间快到了，我们这边可以提前帮您准备好替换件，您看什么时候方便更换？', scenario: '配件更换' },
                { stage: '售后跟进', title: '投诉处理', content: '非常抱歉给您带来不便，请您把具体问题告诉我，我们会第一时间为您解决，并做好后续跟踪。', scenario: '投诉处理' },
                { stage: '售后跟进', title: '问题解决', content: '您之前反馈的XX问题，我们已经处理好了。现在使用正常吗？还有其他需要帮忙的吗？', scenario: '问题解决' },
                { stage: '售后跟进', title: '再次采购', content: '您好，之前采购的产品快用完了吧？需要我们安排补货吗？提前下单可以保证准时供货。', scenario: '再次采购' },
                { stage: '售后跟进', title: '客户关怀', content: '您好，最近天气变化较大，请注意产品存放环境。如有任何使用问题，随时联系我们。', scenario: '客户关怀' },
                { stage: '售后跟进', title: '意见征集', content: '您对我们产品和服务有什么建议吗？您的意见对我们非常重要，可以帮助我们不断改进。', scenario: '意见征集' },
                { stage: '售后跟进', title: '长期合作', content: '感谢您一直以来的支持！我们希望与您建立长期稳定的合作关系，后续有任何需求随时找我。', scenario: '长期合作' }
            ];
            
            for (const scriptData of defaultScripts) {
                await this.dbPut('scripts', {
                    id: this.generateId(),
                    ...scriptData,
                    createdAt: new Date().toISOString()
                });
            }
        }

        // 初始化默认产品
        const products = await this.dbGetAll('products');
        if (products.length === 0) {
            const defaultProducts = [
                {
                    id: this.generateId(),
                    name: '办公桌椅套装',
                    category: '办公设备',
                    images: [],
                    description: '高品质办公桌椅，人体工学设计，适合长时间办公',
                    price: 1299,
                    spec: '标准配置',
                    stock: '有货',
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: 'LED节能灯管',
                    category: '建材类',
                    images: [],
                    description: '高效节能，寿命长，亮度均匀',
                    price: 45,
                    spec: '1.2米',
                    stock: '有货',
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '无线鼠标键盘套装',
                    category: '电子产品',
                    images: [],
                    description: '2.4G无线连接，静音设计，续航持久',
                    price: 168,
                    spec: '无线2.4G',
                    stock: '有货',
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: 'A4复印纸',
                    category: '办公设备',
                    images: [],
                    description: '原生木浆，白度高，不卡纸',
                    price: 28,
                    spec: '500张/包',
                    stock: '有货',
                    createdAt: new Date().toISOString()
                }
            ];
            for (const product of defaultProducts) {
                await this.dbPut('products', product);
            }
        }

        // 初始化客户数据
        const customers = await this.dbGetAll('customers');
        if (customers.length === 0) {
            const now = new Date();
            const adminUser = users.find(u => u.role === 'admin');
            const adminId = adminUser ? adminUser.id : null;

            const defaultCustomers = [
                {
                    id: this.generateId(),
                    name: '张三',
                    phone: '13800138001',
                    company: '郑州建材有限公司',
                    businessScope: ['建材', '其他'],
                    province: '河南省',
                    city: '郑州市',
                    district: '金水区',
                    address: '金水区花园路100号',
                    remark: '长期合作客户',
                    photos: [],
                    level: 'A',
                    region: 'core',
                    returnVisitDays: 7,
                    lastVisitDate: this.getDateString(new Date(now - 7 * 24 * 60 * 60 * 1000)),
                    nextVisitDate: this.getDateString(now),
                    stage: '需求了解',
                    status: 'active',
                    ownerUsers: adminId ? [adminId] : [],
                    createdAt: new Date().toISOString(),
                    updatedAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '李四',
                    phone: '13800138002',
                    company: '洛阳电子科技',
                    businessScope: ['电子产品'],
                    province: '河南省',
                    city: '洛阳市',
                    district: '西工区',
                    address: '西工区中州大道200号',
                    remark: '潜在客户',
                    photos: [],
                    level: 'B',
                    region: 'othercity',
                    returnVisitDays: 15,
                    lastVisitDate: this.getDateString(new Date(now - 10 * 24 * 60 * 60 * 1000)),
                    nextVisitDate: this.getDateString(new Date(now + 5 * 24 * 60 * 60 * 1000)),
                    stage: '产品介绍',
                    status: 'active',
                    ownerUsers: adminId ? [adminId] : [],
                    createdAt: new Date().toISOString(),
                    updatedAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '王五',
                    phone: '13800138003',
                    company: '北京贸易公司',
                    businessScope: ['服装', '食品'],
                    province: '北京市',
                    city: '北京市',
                    district: '朝阳区',
                    address: '朝阳区建国路88号',
                    remark: '新开发客户',
                    photos: [],
                    level: 'C',
                    region: 'domestic',
                    returnVisitDays: 30,
                    lastVisitDate: this.getDateString(new Date(now - 20 * 24 * 60 * 60 * 1000)),
                    nextVisitDate: this.getDateString(new Date(now + 10 * 24 * 60 * 60 * 1000)),
                    stage: '初次接触',
                    status: 'active',
                    ownerUsers: adminId ? [adminId] : [],
                    createdAt: new Date().toISOString(),
                    updatedAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '赵六',
                    phone: '13800138004',
                    company: '开封食品加工厂',
                    businessScope: ['食品'],
                    province: '河南省',
                    city: '开封市',
                    district: '龙亭区',
                    address: '龙亭区宋都大道50号',
                    remark: '重点跟进客户',
                    photos: [],
                    level: 'A',
                    region: 'othercity',
                    returnVisitDays: 7,
                    lastVisitDate: this.getDateString(new Date(now - 15 * 24 * 60 * 60 * 1000)),
                    nextVisitDate: this.getDateString(new Date(now - 8 * 24 * 60 * 60 * 1000)),
                    stage: '异议处理',
                    status: 'active',
                    ownerUsers: adminId ? [adminId] : [],
                    createdAt: new Date().toISOString(),
                    updatedAt: new Date().toISOString()
                }
            ];
            for (const customer of defaultCustomers) {
                await this.dbPut('customers', customer);
            }
        }
        
        // 初始化默认经营范围 - 使用统一的 main 设置记录
        const mainSettings = await this.dbGet('settings', 'main');
        if (!mainSettings || !mainSettings.businessScopes) {
            await this.dbPut('settings', {
                id: 'main',
                businessScopes: ['建材', '电子产品', '服装', '食品', '服务业', '其他'],
                createdAt: new Date().toISOString()
            });
        }
        
        // 初始化默认行业方案（简化版：只保留名称、备注、图片）
        const schemes = await this.dbGetAll('industry_schemes');
        if (schemes.length === 0) {
            const defaultSchemes = [
                {
                    id: this.generateId(),
                    name: '超市方案一',
                    remark: '适用于中小型超市的标准化方案',
                    image: null,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '超市方案二',
                    remark: '智能化管理的超市解决方案',
                    image: null,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '餐饮方案一',
                    remark: '适用于连锁餐饮的标准方案',
                    image: null,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '餐饮方案二',
                    remark: '高端餐饮定制方案',
                    image: null,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '建材方案一',
                    remark: '建材零售展示方案',
                    image: null,
                    createdAt: new Date().toISOString()
                },
                {
                    id: this.generateId(),
                    name: '建材方案二',
                    remark: '建材批发渠道方案',
                    image: null,
                    createdAt: new Date().toISOString()
                }
            ];
            for (const scheme of defaultSchemes) {
                await this.dbPut('industry_schemes', scheme);
            }
        }
    },

    // 获取当前用户可访问的客户列表
    async getCustomers() {
        const customers = await this.dbGetAll('customers');
        
        // admin可以查看所有客户
        if (this.currentUser && this.currentUser.role === 'admin') {
            return customers;
        }
        
        // 其他用户只能查看自己名下的客户
        if (this.currentUser) {
            return customers.filter(c => c.ownerUsers && c.ownerUsers.includes(this.currentUser.id));
        }
        
        return [];
    },

    // 获取可分配的所有用户列表（用于客户归属选择）
    async getAllUsers() {
        return await this.dbGetAll('users');
    },

    // 获取所有权限组
    async getAllPermissionGroups() {
        return await this.dbGetAll('permission_groups');
    },

    // 获取当前用户的权限组
    async getCurrentUserPermissionGroup() {
        if (!this.currentUser) return null;
        
        // 管理员自动拥有所有权限
        if (this.currentUser.role === 'admin') {
            return {
                id: 'admin',
                name: '管理员',
                permissions: Object.keys(this.PERMISSIONS).reduce((acc, category) => {
                    Object.keys(this.PERMISSIONS[category]).forEach(perm => {
                        acc.push(`${category}.${perm}`);
                    });
                    return acc;
                }, [])
            };
        }
        
        const groups = await this.getAllPermissionGroups();
        return groups.find(g => g.code === this.currentUser.permissionGroup) || null;
    },

    // 检查当前用户是否有指定权限
    async hasPermission(permission) {
        if (!this.currentUser) return false;
        
        // 管理员拥有所有权限
        if (this.currentUser.role === 'admin') {
            return true;
        }
        
        const group = await this.getCurrentUserPermissionGroup();
        if (!group || !group.permissions) return false;
        
        return group.permissions.includes(permission);
    },

    // 获取可分配的非管理员用户（用于客户归属选择）
    async getAssignableUsers() {
        const users = await this.getAllUsers();
        // 排除管理员角色
        return users.filter(u => u.role !== 'admin' && u.status === 'active');
    },

    // 初始化登录页面
    async initLogin() {
        var savedUserId = localStorage.getItem('crv_current_user_id');
        if (savedUserId) {
            var user = await this.dbGet('users', savedUserId);
            if (user && user.status === 'active') {
                this.currentUser = user;
                this.showMainApp();
                return;
            }
        }
        // 立即生成验证码，确保在登录前可用
        this.generateCaptcha();
    },

    // 生成验证码（算术题）
    generateCaptcha() {
        // 生成简单算术题
        var a = Math.floor(Math.random() * 5) + 1;
        var b = Math.floor(Math.random() * 5) + 1;
        var result = a + b;
        
        // 存储答案
        this.currentCaptcha = result.toString();
        
        // 显示题目
        var el = document.getElementById('captchaText');
        if (el) {
            el.textContent = a + '+' + b + '=?';
        }
    },

    // 初始化事件监听
    initEventListeners() {
        // 登录表单提交
        document.getElementById('loginForm').addEventListener('submit', (e) => {
            e.preventDefault();
            this.handleLogin();
        });

        // 验证码点击刷新
        var captchaText = document.getElementById('captchaText');
        if (captchaText) {
            captchaText.addEventListener('click', () => {
                this.generateCaptcha();
            });
        }

        // 登出按钮
        document.getElementById('logoutBtn').addEventListener('click', () => {
            this.handleLogout();
        });

        // 移动端菜单
        document.getElementById('mobileMenuBtn').addEventListener('click', () => {
            document.getElementById('sidebar').classList.toggle('active');
        });

        // 侧边栏导航点击
        document.querySelectorAll('.sidebar-nav li').forEach(item => {
            item.addEventListener('click', () => {
                const page = item.dataset.page;
                if (page) {
                    this.navigateTo(page);
                    // 移动端关闭侧边栏
                    if (window.innerWidth < 768) {
                        document.getElementById('sidebar').classList.remove('active');
                    }
                }
            });
        });

        // 回访提醒标签切换
        document.querySelectorAll('.visit-tab').forEach(tab => {
            tab.addEventListener('click', () => {
                document.querySelectorAll('.visit-tab').forEach(t => t.classList.remove('active'));
                tab.classList.add('active');
                this.renderVisitReminder(tab.dataset.tab);
            });
        });

        // 新增客户按钮
        document.getElementById('addCustomerBtn').addEventListener('click', () => {
            this.openCustomerModal();
        });

        // 新增话术按钮
        document.getElementById('addScriptBtn').addEventListener('click', () => {
            this.openScriptModal();
        });

        // 新增产品按钮
        document.getElementById('addProductBtn').addEventListener('click', () => {
            this.openProductModal();
        });

        // 新增用户按钮
        document.getElementById('addUserBtn').addEventListener('click', () => {
            this.openUserModal();
        });

        // 新增权限组按钮
        document.getElementById('addPermissionGroupBtn').addEventListener('click', () => {
            this.openPermissionGroupModal();
        });

        // 满意度评分交互
        document.querySelectorAll('.rating-star').forEach(star => {
            star.addEventListener('click', () => {
                const value = parseInt(star.dataset.value);
                document.getElementById('visitSatisfaction').value = value;
                document.querySelectorAll('.rating-star').forEach((s, index) => {
                    if (index < value) {
                        s.classList.add('active');
                    } else {
                        s.classList.remove('active');
                    }
                });
            });
        });

        // 导出客户按钮（Excel格式）
        document.getElementById('exportCustomerBtn').addEventListener('click', () => {
            this.exportCustomersExcel();
        });

        // 通知按钮
        document.getElementById('headerNotice').addEventListener('click', () => {
            document.getElementById('notificationPanel').classList.toggle('active');
        });

        // 搜索客户回车事件
        document.getElementById('customerSearch').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                this.searchCustomers();
            }
        });

        // 搜索产品回车事件
        document.getElementById('productSearch').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                this.searchProducts();
            }
        });

        // 个人资料表单
        document.getElementById('profileForm').addEventListener('submit', (e) => {
            e.preventDefault();
            this.saveProfile();
        });

        // 路由处理
        window.addEventListener('hashchange', () => {
            const hash = window.location.hash.slice(1);
            if (hash) {
                this.navigateTo(hash);
            }
        });

        // 云同步菜单事件（Electron 主进程触发）
        if (window.electronAPI && window.electronAPI.onMenuAction) {
            window.electronAPI.onMenuAction(async (action) => {
                if (action === 'cloud-upload') {
                    await this.syncExportToFile();
                } else if (action === 'cloud-download') {
                    await this.syncImportFromFile();
                } else if (action === 'export-customers') {
                    await this.exportData();
                } else if (action === 'backup') {
                    await this.exportDataBackup();
                }
            });
        }
    },

    // 处理登录
    async handleLogin() {
        // 检查数据库是否已准备好
        if (!this.dbReady || !this.db) {
            document.getElementById('loginError').textContent = '系统初始化中，请稍后再试...';
            console.log('数据库未准备好，dbReady:', this.dbReady, 'db:', this.db);
            return;
        }

        const username = document.getElementById('username').value.trim();
        const password = document.getElementById('password').value;
        const captcha = document.getElementById('captcha').value.trim();
        const rememberMe = document.getElementById('rememberMe').checked;

        // 验证验证码 - 支持字符串和数字比较
        const expectedCaptcha = this.currentCaptcha ? this.currentCaptcha.toString() : '';
        if (!captcha || captcha !== expectedCaptcha) {
            document.getElementById('loginError').textContent = '验证码错误，请重试 (正确答案是: ' + expectedCaptcha + ')';
            document.getElementById('captcha').value = '';
            this.generateCaptcha();
            return;
        }

        // 检查账号是否被锁定
        const lockKey = 'crv_lock_' + username;
        const lockData = JSON.parse(localStorage.getItem(lockKey) || '{}');
        if (lockData.locked && lockData.until > Date.now()) {
            const mins = Math.ceil((lockData.until - Date.now()) / 60000);
            document.getElementById('loginError').textContent = `账号已锁定，请${mins}分钟后再试`;
            this.generateCaptcha();
            return;
        }

        // 验证用户
        const users = await this.getAllUsers();
        const user = users.find(u => u.username === username);
        
        if (!user) {
            document.getElementById('loginError').textContent = '用户名或密码错误';
            this.generateCaptcha();
            return;
        }

        // 验证密码（异步）
        const passwordValid = await this.verifyPassword(password, user.password);
        if (!passwordValid) {
            // 失败计数
            const failKey = 'crv_fail_' + username;
            const fails = (parseInt(localStorage.getItem(failKey) || '0')) + 1;
            if (fails >= 5) {
                localStorage.setItem(lockKey, JSON.stringify({ locked: true, until: Date.now() + 15 * 60 * 1000 }));
                localStorage.removeItem(failKey);
                document.getElementById('loginError').textContent = '密码错误次数过多，账号锁定15分钟';
            } else {
                localStorage.setItem(failKey, fails);
                document.getElementById('loginError').textContent = `用户名或密码错误（还可尝试${5 - fails}次）`;
            }
            this.generateCaptcha();
            return;
        }
        
        // 登录成功，清除失败计数
        localStorage.removeItem('crv_fail_' + username);
        localStorage.removeItem(lockKey);


        if (user.status !== 'active') {
            document.getElementById('loginError').textContent = '账号已被禁用';
            this.generateCaptcha();
            return;
        }

        // 登录成功
        this.currentUser = user;
        
        if (rememberMe) {
            localStorage.setItem('crv_current_user_id', user.id);
        }

        document.getElementById('loginError').textContent = '';
        this.showMainApp();
    },

    // 处理登出
    handleLogout() {
        this.currentUser = null;
        localStorage.removeItem('crv_current_user_id');
        document.getElementById('loginPage').style.display = 'flex';
        document.getElementById('mainApp').style.display = 'none';
        document.getElementById('username').value = '';
        document.getElementById('password').value = '';
        document.getElementById('captcha').value = '';
    },

    // 显示主应用
    showMainApp() {
        document.getElementById('loginPage').style.display = 'none';
        document.getElementById('mainApp').style.display = 'flex';
        
        // 设置当前用户信息
        document.getElementById('currentUserName').textContent = this.currentUser.realName;
        document.getElementById('currentUserRole').textContent = this.getRoleName(this.currentUser.role);

        // 根据角色显示/隐藏菜单
        if (this.currentUser.role !== 'admin') {
            document.getElementById('menuUsers').style.display = 'none';
            document.getElementById('menuPermissionGroups').style.display = 'none';
        } else {
            document.getElementById('menuUsers').style.display = 'block';
            document.getElementById('menuPermissionGroups').style.display = 'block';
        }

        // 加载首页
        this.navigateTo('dashboard');
    },

    // 页面导航
    async navigateTo(page) {
        // 更新侧边栏
        document.querySelectorAll('.sidebar-nav li').forEach(item => {
            item.classList.toggle('active', item.dataset.page === page);
        });

        // 更新内容区域
        document.querySelectorAll('.page-content').forEach(content => {
            content.classList.remove('active');
        });

        const pageElement = document.getElementById('page' + this.capitalize(page));
        if (pageElement) {
            pageElement.classList.add('active');
        }

        // 更新标题
        const titles = {
            dashboard: '首页',
            customers: '客户管理',
            classify: '客户分类',
            scripts: '回访话术',
            products: '产品展示',
            users: '用户权限',
            permissionGroups: '权限组管理',
            settings: '系统设置',
            statistics: '数据统计'
        };
        const pageTitle = titles[page] || '首页';
        document.getElementById('pageTitle').textContent = pageTitle;
        
        // 更新手机端标题
        const mobilePageTitle = document.getElementById('mobilePageTitle');
        if (mobilePageTitle) {
            mobilePageTitle.textContent = pageTitle;
        }

        // 更新手机端底部导航激活状态
        document.querySelectorAll('.mobile-nav-item').forEach(item => {
            item.classList.toggle('active', item.dataset.page === page);
        });

        // 加载对应页面数据
        switch (page) {
            case 'dashboard':
                this.loadDashboard();
                break;
            case 'customers':
                this.loadCustomers();
                break;
            case 'classify':
                this.loadClassify();
                break;
            case 'scripts':
                this.loadScripts();
                break;
            case 'products':
                this.loadProducts();
                break;
            case 'users':
                this.loadUsers();
                break;
            case 'permissionGroups':
                this.loadPermissionGroups();
                break;
            case 'settings':
                this.loadSettings();
                break;
            case 'statistics':
                this.loadStatistics();
                break;
        }
    },

    // ==================== 首页相关 ====================
    async loadDashboard() {
        // 第一步：并行加载统计卡片 + 回访提醒（用户马上能看到内容）
        await Promise.all([
            this.renderStats(),
            this.renderVisitReminder('today'),
            this.updateNotificationBadge(),
            this.checkAndSendVisitReminders()
        ]);
        // 第二步：地图异步渲染，不阻塞上方内容展示
        // 用 setTimeout 0 让浏览器先完成一帧渲染，再启动地图
        setTimeout(() => { this.renderCustomerMap(); }, 0);
    },

    // ==================== 数据统计 ====================
    async loadStatistics() {
        // 加载用户选项
        await this.loadStatisticsUserFilter();
        // 执行筛选统计
        await this.filterStatistics();
    },

    // 加载用户筛选选项
    async loadStatisticsUserFilter() {
        const users = await this.getAllUsers();
        const userSelect = document.getElementById('statisticsUserFilter');
        userSelect.innerHTML = '<option value="">全部用户</option>';
        users.forEach(user => {
            const option = document.createElement('option');
            option.value = user.id;
            option.textContent = user.realName;
            userSelect.appendChild(option);
        });
    },

    // 筛选统计数据
    async filterStatistics() {
        const dateRange = document.getElementById('statisticsDateRange').value;
        const userFilter = document.getElementById('statisticsUserFilter').value;
        const startDateStr = document.getElementById('statisticsStartDate')?.value;
        const endDateStr = document.getElementById('statisticsEndDate')?.value;

        // 计算日期范围
        let startDate = null;
        let endDate = null;
        const today = new Date();
        today.setHours(0, 0, 0, 0);

        if (dateRange === 'today') {
            startDate = today;
            endDate = new Date(today);
            endDate.setDate(endDate.getDate() + 1);
        } else if (dateRange === 'week') {
            const dayOfWeek = today.getDay();
            startDate = new Date(today);
            startDate.setDate(today.getDate() - dayOfWeek);
            endDate = new Date(today);
            endDate.setDate(today.getDate() + (7 - dayOfWeek));
        } else if (dateRange === 'month') {
            startDate = new Date(today.getFullYear(), today.getMonth(), 1);
            endDate = new Date(today.getFullYear(), today.getMonth() + 1, 0);
        } else if (dateRange === 'quarter') {
            const quarter = Math.floor(today.getMonth() / 3);
            startDate = new Date(today.getFullYear(), quarter * 3, 1);
            endDate = new Date(today.getFullYear(), (quarter + 1) * 3, 0);
        } else if (dateRange === 'year') {
            startDate = new Date(today.getFullYear(), 0, 1);
            endDate = new Date(today.getFullYear(), 11, 31);
        } else if (dateRange === 'custom' && startDateStr && endDateStr) {
            startDate = new Date(startDateStr);
            startDate.setHours(0, 0, 0, 0);
            endDate = new Date(endDateStr);
            endDate.setHours(23, 59, 59, 999);
        }

        // 显示/隐藏自定义日期范围
        const customDateRangeEl = document.getElementById('customDateRange');
        if (customDateRangeEl) {
            customDateRangeEl.style.display = dateRange === 'custom' ? 'flex' : 'none';
        }

        // 获取所有数据
        const customers = await this.getCustomers();
        const visitRecords = await this.dbGetAll('visit_records');
        const users = await this.getAllUsers();

        // 过滤客户
        let filteredCustomers = customers.filter(c => c.status === 'active');

        // 按用户过滤
        if (userFilter) {
            filteredCustomers = filteredCustomers.filter(c =>
                c.ownerUsers && c.ownerUsers.includes(userFilter)
            );
        }

        // 按日期范围过滤（基于客户创建时间）
        if (startDate && endDate) {
            filteredCustomers = filteredCustomers.filter(c => {
                if (!c.createdAt) return false;
                const createdDate = new Date(c.createdAt);
                return createdDate >= startDate && createdDate <= endDate;
            });
        }

        const todayStr = this.getDateString(new Date());

        // 更新统计卡片
        document.getElementById('statTotalCustomers2').textContent = filteredCustomers.length;
        document.getElementById('statOverdueCount').textContent =
            filteredCustomers.filter(c => c.nextVisitDate < todayStr).length;

        // 过滤回访记录
        let filteredVisitRecords = visitRecords;

        // 按用户过滤回访记录
        if (userFilter) {
            // 查找该用户负责的客户ID
            const userCustomerIds = filteredCustomers.map(c => c.id);
            filteredVisitRecords = visitRecords.filter(r =>
                userCustomerIds.includes(r.customerId)
            );
        }

        // 按日期范围过滤回访记录
        if (startDate && endDate) {
            filteredVisitRecords = filteredVisitRecords.filter(r => {
                if (!r.createdAt) return false;
                const visitDate = new Date(r.createdAt);
                return visitDate >= startDate && visitDate <= endDate;
            });
        }

        document.getElementById('statVisitTotal').textContent = filteredVisitRecords.length;

        // 计算平均满意度
        const ratedRecords = filteredVisitRecords.filter(r => r.satisfaction > 0);
        if (ratedRecords.length > 0) {
            const avg = ratedRecords.reduce((sum, r) => sum + r.satisfaction, 0) / ratedRecords.length;
            document.getElementById('statAvgSatisfaction').textContent = '★ ' + avg.toFixed(1);
        } else {
            document.getElementById('statAvgSatisfaction').textContent = '-';
        }

        // 延迟渲染图表（确保容器已渲染）
        setTimeout(async () => {
            await this.renderCharts(filteredCustomers, filteredVisitRecords, startDate, endDate);
        }, 100);

        // 渲染近期回访记录
        await this.renderRecentVisitTable(filteredVisitRecords, customers);
    },

    // 重置统计筛选
    async resetStatisticsFilter() {
        document.getElementById('statisticsDateRange').value = 'all';
        document.getElementById('statisticsUserFilter').value = '';
        const customDateRangeEl = document.getElementById('customDateRange');
        if (customDateRangeEl) customDateRangeEl.style.display = 'none';
        const startDateEl = document.getElementById('statisticsStartDate');
        const endDateEl = document.getElementById('statisticsEndDate');
        if (startDateEl) startDateEl.value = '';
        if (endDateEl) endDateEl.value = '';
        await this.filterStatistics();
    },

    async renderRecentVisitTable(visitRecords, customers) {
        const tbody = document.getElementById('recentVisitTableBody');
        if (!tbody) return;
        
        const recent = [...visitRecords].sort((a, b) => new Date(b.visitDate) - new Date(a.visitDate)).slice(0, 20);
        
        if (recent.length === 0) {
            tbody.innerHTML = '<tr><td colspan="6" class="empty-state">暂无回访记录</td></tr>';
            return;
        }
        
        tbody.innerHTML = recent.map(r => {
            const customer = customers.find(c => c.id === r.customerId);
            const stars = r.satisfaction ? '★'.repeat(r.satisfaction) + '☆'.repeat(5 - r.satisfaction) : '-';
            return `
                <tr>
                    <td><strong>${customer ? customer.name : '未知客户'}</strong></td>
                    <td>${r.method || '-'}</td>
                    <td>${r.stage || '-'}</td>
                    <td style="color:#F59E0B;">${stars}</td>
                    <td style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${r.content || '-'}</td>
                    <td>${r.visitDate || '-'}</td>
                </tr>
            `;
        }).join('');
    },


    async renderStats() {
        const customers = await this.getCustomers();
        const activeCustomers = customers.filter(c => c.status === 'active');
        
        const today = this.getDateString(new Date());
        const nextWeek = this.getDateString(new Date(Date.now() + 7 * 24 * 60 * 60 * 1000));

        const todayVisit = activeCustomers.filter(c => c.nextVisitDate === today).length;
        const weekVisit = activeCustomers.filter(c => c.nextVisitDate >= today && c.nextVisitDate <= nextWeek).length;
        const levelA = activeCustomers.filter(c => c.level === 'A').length;

        document.getElementById('statTotalCustomers').textContent = activeCustomers.length;
        document.getElementById('statTodayVisit').textContent = todayVisit;
        document.getElementById('statWeekVisit').textContent = weekVisit;
        document.getElementById('statLevelA').textContent = levelA;
    },

    async renderCustomerMap() {
        const customers = await this.getCustomers();

        // 统计各省客户数量
        const provinceStats = {};
        const henanCityStats = {};

        customers.forEach(c => {
            if (c.province) {
                const provinceName = c.province.replace(/省|市|自治区|特别行政区/g, '');
                provinceStats[provinceName] = (provinceStats[provinceName] || 0) + 1;

                // 统计河南省内地市
                if (c.province === '河南省' && c.city) {
                    henanCityStats[c.city] = (henanCityStats[c.city] || 0) + 1;
                }
            }
        });

        // 渲染中国地图和河南省地图（并行，互不依赖）
        await Promise.all([
            this.renderChinaEchartsMap(provinceStats),
            this.renderHenanEchartsMap(henanCityStats)
        ]);
        
        // 渲染省份统计列表
        const statsList = document.getElementById('provinceStatsList');
        if (statsList) {
            // 按客户数量排序
            const sortedProvinces = Object.entries(provinceStats)
                .sort((a, b) => b[1] - a[1]);
            
            if (sortedProvinces.length === 0) {
                statsList.innerHTML = '<div style="text-align:center;color:#999;padding:20px;">暂无客户数据</div>';
            } else {
                statsList.innerHTML = sortedProvinces.map(([province, count]) => `
                    <div style="display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; margin-bottom: 6px; background: ${province === '河南省' ? '#fef3c7' : '#f3f4f6'}; border-radius: 6px; cursor: pointer; transition: all 0.2s;" onclick="app.showProvinceCustomers('${province}')">
                        <span style="font-size: 14px;">${province}</span>
                        <span style="font-size: 14px; font-weight: 600; color: #e94560;">${count}人</span>
                    </div>
                `).join('');
            }
        }
        
        // 渲染河南省地市统计列表
        const henanCityStatsList = document.getElementById('henanCityStatsList');
        if (henanCityStatsList) {
            const henanCities = ["郑州市", "开封市", "洛阳市", "平顶山市", "安阳市", "鹤壁市", "新乡市", "焦作市", "濮阳市", "许昌市", "漯河市", "三门峡市", "南阳市", "商丘市", "信阳市", "周口市", "驻马店市", "济源市"];
            
            const sortedCities = henanCities.map(city => ({
                name: city,
                count: henanCityStats[city] || 0
            })).sort((a, b) => b.count - a.count);
            
            if (sortedCities.every(c => c.count === 0)) {
                henanCityStatsList.innerHTML = '<div style="text-align:center;color:#999;padding:20px;">暂无客户数据</div>';
            } else {
                henanCityStatsList.innerHTML = sortedCities.map(({ name, count }) => `
                    <div style="display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; margin-bottom: 6px; background: ${count > 0 ? '#fffbeb' : '#f3f4f6'}; border-radius: 6px; cursor: pointer; transition: all 0.2s;" onclick="app.showCityCustomers('${name}')">
                        <span style="font-size: 14px;">${name.replace('市', '')}</span>
                        <span style="font-size: 14px; font-weight: 600; color: ${count > 0 ? '#e94560' : '#9ca3af'};">${count}人</span>
                    </div>
                `).join('');
            }
        }
    },

    // 显示省份客户列表
    async showProvinceCustomers(provinceName) {
        const customers = await this.getCustomers();
        const filteredCustomers = customers.filter(c => {
            const province = c.province ? c.province.replace(/省|市|自治区|特别行政区/g, '') : '';
            return province === provinceName;
        });

        if (filteredCustomers.length === 0) {
            this.showNotification(`${provinceName}暂无客户`, 'info');
            return;
        }

        // 跳转到客户管理页面并应用筛选
        document.getElementById('customerProvinceFilter').value = provinceName.includes('河南') ? '河南省' : provinceName + (this.getProvinceSuffix(provinceName) || '省');
        this.filterCustomers();
        this.navigateTo('customers');
        this.showNotification(`${provinceName}共有${filteredCustomers.length}位客户`, 'success');
    },

    // 显示城市客户列表
    async showCityCustomers(cityName) {
        const customers = await this.getCustomers();
        const filteredCustomers = customers.filter(c => c.city === cityName);

        if (filteredCustomers.length === 0) {
            this.showNotification(`${cityName}暂无客户`, 'info');
            return;
        }

        // 跳转到客户管理页面并显示筛选后的客户
        // 由于城市筛选器可能没有该城市,我们直接显示筛选后的列表
        this.renderCustomerTable(filteredCustomers);
        this.navigateTo('customers');
        this.showNotification(`${cityName}共有${filteredCustomers.length}位客户`, 'success');
    },

    // 获取省份后缀
    getProvinceSuffix(provinceName) {
        const suffixes = {
            '北京': '市', '天津': '市', '上海': '市', '重庆': '市',
            '内蒙古': '自治区', '广西': '壮族自治区', '西藏': '自治区',
            '宁夏': '回族自治区', '新疆': '维吾尔自治区',
            '香港': '特别行政区', '澳门': '特别行政区'
        };
        return suffixes[provinceName] || '省';
    },

    // ==================== ECharts 地图渲染 ====================

    // 中国ECharts地图实例
    _chinaChart: null,
    _henanChart: null,

    // 渲染中国ECharts地图
    async renderChinaEchartsMap(provinceStats) {
        const el = document.getElementById('chinaMapChart');
        if (!el) { console.warn('未找到 chinaMapChart 元素'); return; }

        // 如果没有ECharts则降级
        if (typeof echarts === 'undefined') { console.warn('ECharts未加载'); return; }

        // 检查是否已注册中国地图
        if (!echarts.getMap('china')) {
            // 使用内嵌的全局变量加载中国地图数据，避免file://协议下fetch失败
            try {
                if (Object.keys(this.chinaMapPaths).length === 0) {
                    if (typeof CHINA_MAP_DATA !== 'undefined') {
                        CHINA_MAP_DATA.forEach(item => { this.chinaMapPaths[item.name] = item.svg; });
                    } else {
                        console.error('中国地图数据未加载(CHINA_MAP_DATA undefined)');
                        return;
                    }
                }
                // 构建 SVG 字符串并注册
                const svgPaths = Object.entries(this.chinaMapPaths).map(([name, d]) =>
                    `<path name="${name}" d="${d}"/>`
                ).join('');
                const svgStr = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 450">${svgPaths}</svg>`;
                echarts.registerMap('china', { svg: svgStr });
            } catch(e) {
                console.error('中国地图数据加载失败:', e);
                return;
            }
        }

        // 复用实例，已有则直接更新数据，无需重建
        if (!this._chinaChart || this._chinaChart.isDisposed()) {
            this._chinaChart = echarts.init(el);
        }


        // 构建数据
        const mapData = Object.entries(this.chinaMapPaths).map(([name]) => ({
            name,
            value: provinceStats[name] || 0
        }));

        const option = {
            tooltip: {
                trigger: 'item',
                formatter: (params) => {
                    const suffix = this.getProvinceSuffix(params.name) || '';
                    return `${params.name}${suffix}<br/>客户数: <b>${params.value || 0}</b> 人`;
                }
            },
            visualMap: {
                min: 0,
                max: Math.max(50, ...Object.values(provinceStats)),
                text: ['多', '少'],
                realtime: false,
                calculable: false,
                inRange: {
                    color: ['#e2e8f0', '#93C5FD', '#3B82F6', '#1D4ED8']
                },
                textStyle: { color: '#666', fontSize: 11 },
                bottom: 10,
                left: 10,
                itemWidth: 14,
                itemHeight: 80
            },
            series: [{
                name: '客户分布',
                type: 'map',
                map: 'china',
                roam: false,
                emphasis: {
                    label: { show: true, fontSize: 10, color: '#fff' },
                    itemStyle: { areaColor: '#F59E0B', shadowBlur: 6, shadowColor: 'rgba(0,0,0,0.3)' }
                },
                select: { disabled: true },
                itemStyle: {
                    borderColor: '#fff',
                    borderWidth: 1
                },
                label: { show: false },
                data: mapData,
                // 河南省特殊颜色
                nameMap: {},
            }]
        };

        // 河南省单独设置颜色覆盖
        const henanCount = provinceStats['河南'] || 0;
        if (henanCount > 0) {
            const henanData = option.series[0].data.find(d => d.name === '河南');
            if (henanData) {
                henanData.itemStyle = { areaColor: '#F59E0B' };
                henanData.emphasis = { itemStyle: { areaColor: '#EA580C' } };
            }
        } else {
            const henanData = option.series[0].data.find(d => d.name === '河南');
            if (henanData) {
                henanData.itemStyle = { areaColor: '#fef3c7' };
                henanData.emphasis = { itemStyle: { areaColor: '#FCD34D' } };
            }
        }

        this._chinaChart.setOption(option);

        // 点击事件
        this._chinaChart.on('click', (params) => {
            if (params.name) {
                this.showProvinceCustomers(params.name);
            }
        });

        // 响应式
        window.addEventListener('resize', () => {
            if (this._chinaChart) this._chinaChart.resize();
        });
    },

    // 渲染河南省ECharts地图（使用真实GeoJSON）
    async renderHenanEchartsMap(henanCityStats) {
        const el = document.getElementById('henanMapChart');
        if (!el) { console.warn('未找到 henanMapChart 元素'); return; }

        if (typeof echarts === 'undefined') { console.warn('ECharts未加载'); return; }

        // 注册河南地图（使用内嵌的全局变量，避免file://协议下fetch失败）
        try {
            if (typeof HENAN_GEO_DATA !== 'undefined') {
                echarts.registerMap('henan', HENAN_GEO_DATA);
            } else {
                console.error('河南GeoJSON数据未加载(HENAN_GEO_DATA undefined)');
                return;
            }
        } catch(e) {
            console.error('河南GeoJSON加载失败:', e);
            return;
        }

        // 复用实例，已有则直接更新数据
        if (!this._henanChart || this._henanChart.isDisposed()) {
            this._henanChart = echarts.init(el);
        }


        const henanCityNames = ['郑州市','开封市','洛阳市','平顶山市','安阳市','鹤壁市','新乡市',
            '焦作市','濮阳市','许昌市','漯河市','三门峡市','南阳市','商丘市',
            '信阳市','周口市','驻马店市','济源市'];

        const mapData = henanCityNames.map(name => ({
            name,
            value: henanCityStats[name] || 0
        }));

        const maxVal = Math.max(1, ...Object.values(henanCityStats));

        const option = {
            tooltip: {
                trigger: 'item',
                formatter: (params) => `${params.name}<br/>客户数: <b>${params.value || 0}</b> 人`
            },
            visualMap: {
                min: 0,
                max: Math.max(20, maxVal),
                text: ['多', '少'],
                realtime: false,
                calculable: false,
                inRange: {
                    color: ['#fef3c7', '#FCD34D', '#F59E0B', '#EA580C']
                },
                textStyle: { color: '#666', fontSize: 11 },
                bottom: 10,
                left: 10,
                itemWidth: 14,
                itemHeight: 80
            },
            series: [{
                name: '河南客户分布',
                type: 'map',
                map: 'henan',
                roam: false,
                emphasis: {
                    label: { show: true, fontSize: 11, color: '#fff' },
                    itemStyle: { areaColor: '#FBBF24', shadowBlur: 6, shadowColor: 'rgba(0,0,0,0.3)' }
                },
                select: { disabled: true },
                itemStyle: {
                    borderColor: '#9CA3AF',
                    borderWidth: 1
                },
                label: {
                    show: true,
                    fontSize: 10,
                    color: '#374151',
                    formatter: (params) => {
                        const count = henanCityStats[params.name] || 0;
                        const shortName = params.name.replace('市', '');
                        return count > 0 ? `{a|${shortName}}\n{b|${count}人}` : shortName;
                    },
                    rich: {
                        a: { fontSize: 10, color: '#374151', fontWeight: 'bold', lineHeight: 14 },
                        b: { fontSize: 9, color: '#666', lineHeight: 12 }
                    }
                },
                data: mapData
            }]
        };

        this._henanChart.setOption(option);

        // 点击事件
        this._henanChart.on('click', (params) => {
            if (params.name) {
                this.showCityCustomers(params.name);
            }
        });

        // 响应式
        window.addEventListener('resize', () => {
            if (this._henanChart) this._henanChart.resize();
        });
    },

    // 备用方案：使用 SVG 直接渲染
    renderHenanSvgMapFallback(henanCityStats) {
        console.log('使用 SVG 备用方案渲染河南地图');
        const henanMapChart = document.getElementById('henanMapChart');
        if (!henanMapChart) return;

        try {
            // 如果已有实例，先销毁
            if (this.henanChart) {
                this.henanChart.dispose();
            }

            // 创建 SVG 元素
            henanMapChart.innerHTML = `
                <svg id="henanMapSvg" viewBox="0 0 400 350" style="width: 100%; height: auto;"></svg>
            `;

            const svg = document.getElementById('henanMapSvg');

            // 遍历所有城市路径
            Object.entries(this.henanMapPaths).forEach(([name, pathData]) => {
                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                path.setAttribute('d', pathData);
                path.setAttribute('data-name', name);

                // 获取该城市的客户数量
                const count = henanCityStats[name] || 0;

                // 根据客户数量设置颜色
                if (count > 0) {
                    if (count >= 20) {
                        path.style.fill = '#EA580C'; // 深橙色 - 20+
                    } else if (count >= 6) {
                        path.style.fill = '#F59E0B'; // 橙色 - 6-20
                    } else {
                        path.style.fill = '#FCD34D'; // 浅橙色 - 1-5
                    }
                } else {
                    path.style.fill = '#fef3c7'; // 浅橙色 - 无客户
                }

                path.style.stroke = '#ffffff';
                path.style.strokeWidth = '1';
                path.style.cursor = 'pointer';
                path.style.transition = 'all 0.2s';

                // 添加鼠标悬停效果
                path.addEventListener('mouseenter', () => {
                    path.style.opacity = '0.8';
                    path.style.transform = 'scale(1.02)';
                    path.style.transformOrigin = 'center';
                });

                path.addEventListener('mouseleave', () => {
                    path.style.opacity = '1';
                    path.style.transform = 'scale(1)';
                });

                // 添加点击事件
                path.addEventListener('click', () => {
                    this.showProvinceCustomers(name);
                });

                svg.appendChild(path);
            });

            console.log('河南地图 SVG 备用方案渲染完成');

        } catch (error) {
            console.error('河南地图 SVG 备用方案渲染失败:', error);
        }
    },

    // 中国地图热区配置 - 请根据您的地图图片配置坐标
    chinaMapHotspots: {
        // 格式: "省份名": "x1,y1,x2,y2,x3,y3,..."
        // 您可以使用在线工具生成坐标: https://imagemap-generator.dariodossena.com/
        // 示例坐标(需要根据您的实际图片调整):
        '新疆': '50,80,200,70,220,140,180,180,80,160',
        '西藏': '50,180,170,170,190,260,100,280,40,250',
        '青海': '175,110,250,105,260,160,180,170',
        '甘肃': '215,70,310,65,320,120,280,140,230,135',
        '内蒙古': '300,25,500,15,520,70,420,80,315,75',
        '四川': '245,185,320,180,330,250,270,260,235,225',
        '云南': '220,270,305,265,325,340,240,350,195,315',
        '黑龙江': '500,5,610,10,620,65,520,75',
        '吉林': '520,70,600,65,605,105,530,110',
        '辽宁': '500,115,565,110,575,150,510,155',
        '北京': '460,130,490,127,493,148,463,150',
        '河北': '410,115,490,110,495,170,420,175',
        '山西': '360,135,415,130,420,185,365,190',
        '陕西': '305,155,370,150,375,220,310,225',
        '宁夏': '285,150,315,147,318,180,288,183',
        '山东': '430,170,495,165,500,210,435,215',
        '河南': '370,185,435,180,440,245,375,250',
        '湖北': '375,255,445,250,450,310,380,315',
        '湖南': '365,315,440,310,445,375,370,380',
        '安徽': '440,245,500,240,505,300,450,305',
        '江苏': '490,210,560,205,565,260,505,265',
        '上海': '535,270,565,267,568,290,538,293',
        '浙江': '490,295,545,290,550,350,495,355',
        '江西': '440,320,500,315,505,385,450,390',
        '福建': '470,365,525,360,530,420,475,425',
        '广东': '380,380,480,375,485,445,390,450',
        '广西': '310,365,380,360,385,435,315,440',
        '海南': '385,460,430,458,432,478,387,481',
        '贵州': '280,315,350,310,355,365,285,370',
        '重庆': '300,260,345,255,348,300,303,305',
        '台湾': '550,370,575,365,580,430,555,435',
        '天津': '505,115,530,113,532,130,507,132',
        '香港': '445,415,460,413,461,428,446,430',
        '澳门': '430,420,440,419,441,430,431,431'
    },

    // 河南省地图热区配置 - 请根据您的地图图片配置坐标
    henanMapHotspots: {
        // 格式: "城市名": "x1,y1,x2,y2,x3,y3,..."
        // 您可以使用在线工具生成坐标: https://imagemap-generator.dariodossena.com/
        // 示例坐标(需要根据您的实际图片调整):
        '郑州市': '175,95,220,90,225,135,180,140',
        '开封市': '225,90,280,85,285,130,230,135',
        '洛阳市': '110,115,170,110,175,165,115,170',
        '平顶山市': '175,170,230,165,235,210,180,215',
        '安阳市': '215,35,275,30,280,75,220,80',
        '鹤壁市': '275,30,310,27,313,60,280,63',
        '新乡市': '220,80,285,75,290,115,225,120',
        '焦作市': '160,65,215,60,220,105,165,110',
        '濮阳市': '310,40,365,35,370,80,315,85',
        '许昌市': '230,140,285,135,290,180,235,185',
        '漯河市': '235,190,280,185,283,220,238,225',
        '三门峡市': '65,105,115,100,120,155,70,160',
        '南阳市': '135,175,245,170,250,255,140,265',
        '商丘市': '295,105,365,100,370,155,300,160',
        '信阳市': '195,280,305,275,310,315,200,320',
        '周口市': '295,165,365,160,370,215,300,220',
        '驻马店市': '250,230,345,225,350,275,255,280',
        '济源市': '125,75,160,70,163,100,128,103'
    },

    // 创建地图热区
    createMapHotspots(mapName, hotspots, stats, type) {
        const mapElement = document.getElementById(mapName);
        const imageElement = document.getElementById(mapName + 'Image');

        if (!mapElement || !imageElement) return;

        // 清空现有热区
        mapElement.innerHTML = '';

        // 获取图片实际尺寸
        const imgWidth = imageElement.naturalWidth || 600;
        const imgHeight = imageElement.naturalHeight || 450;

        // 遍历热区配置
        Object.entries(hotspots).forEach(([name, coords]) => {
            const count = stats[name] || 0;

            // 根据客户数量确定颜色
            let color = '#e2e8f0'; // 默认灰色 - 无客户
            if (type === 'province') {
                if (count >= 50) {
                    color = '#1D4ED8'; // 深蓝色 - 50+
                } else if (count >= 11) {
                    color = '#3B82F6'; // 蓝色 - 11-50
                } else if (count > 0) {
                    color = '#93C5FD'; // 浅蓝色 - 1-10
                }
                if (name === '河南' && count > 0) {
                    color = '#FCD34D'; // 河南省特殊颜色
                }
            } else if (type === 'city') {
                if (count >= 20) {
                    color = '#EA580C'; // 深橙色 - 20+
                } else if (count >= 6) {
                    color = '#F59E0B'; // 橙色 - 6-20
                } else if (count > 0) {
                    color = '#FCD34D'; // 浅橙色 - 1-5
                }
            }

            // 创建area元素
            const area = document.createElement('area');
            area.shape = 'poly';
            area.coords = coords;
            area.alt = name;

            // 创建点击事件
            area.onclick = () => {
                if (type === 'province') {
                    this.showProvinceCustomers(name);
                } else if (type === 'city') {
                    this.showCityCustomers(name);
                }
            };

            // 添加title提示
            area.title = `${name}: ${count}人`;

            mapElement.appendChild(area);
        });
    },

    async renderVisitReminder(type = 'today') {
        const customers = await this.getCustomers();
        const activeCustomers = customers.filter(c => c.status === 'active');
        
        const today = this.getDateString(new Date());
        const tomorrow = this.getDateString(new Date(Date.now() + 24 * 60 * 60 * 1000));

        let filteredCustomers = [];
        switch (type) {
            case 'today':
                filteredCustomers = activeCustomers.filter(c => c.nextVisitDate === today);
                break;
            case 'tomorrow':
                filteredCustomers = activeCustomers.filter(c => c.nextVisitDate === tomorrow);
                break;
            case 'overdue':
                filteredCustomers = activeCustomers.filter(c => c.nextVisitDate < today);
                break;
        }

        const listEl = document.getElementById('visitReminderList');
        
        if (filteredCustomers.length === 0) {
            listEl.innerHTML = '<div class="empty-state"><p>暂无待回访客户</p></div>';
            return;
        }

        listEl.innerHTML = filteredCustomers.map(customer => {
            let itemClass = type;
            if (type === 'today') itemClass = 'today';
            if (type === 'tomorrow') itemClass = 'tomorrow';
            if (type === 'overdue') itemClass = 'overdue';

            const daysDiff = this.getDaysDiff(customer.nextVisitDate, today);
            let daysText = '';
            if (daysDiff < 0) {
                daysText = `已过期${Math.abs(daysDiff)}天`;
            } else if (daysDiff === 0) {
                daysText = '今天';
            } else {
                daysText = `${daysDiff}天后`;
            }

            return `
                <div class="visit-item ${itemClass}" onclick="app.showVisitModal('${customer.id}')">
                    <div class="visit-item-info">
                        <div class="visit-item-name">${customer.name} <span class="level-tag ${customer.level}">${customer.level}</span></div>
                        <div class="visit-item-phone">${customer.phone} | ${customer.company || '-'}</div>
                    </div>
                    <div>
                        <div class="visit-item-date">${customer.nextVisitDate}</div>
                        <div class="visit-item-days">${daysText}</div>
                    </div>
                </div>
            `;
        }).join('');
    },

    async renderLevelStats() {
        const customers = await this.getCustomers();
        const activeCustomers = customers.filter(c => c.status === 'active');

        const levelCounts = {
            A: activeCustomers.filter(c => c.level === 'A').length,
            B: activeCustomers.filter(c => c.level === 'B').length,
            C: activeCustomers.filter(c => c.level === 'C').length,
            D: activeCustomers.filter(c => c.level === 'D').length
        };

        document.getElementById('levelStats').innerHTML = ['A', 'B', 'C', 'D'].map(level => `
            <div class="level-stat">
                <div class="level-stat-icon ${level}">
                    <i class="fas fa-star"></i>
                </div>
                <div class="level-stat-value">${levelCounts[level]}</div>
                <div class="level-stat-label">${level}级客户</div>
            </div>
        `).join('');
    },

    async updateNotificationBadge() {
        const customers = await this.getCustomers();
        const today = this.getDateString(new Date());
        const activeCustomers = customers.filter(c => c.status === 'active');
        
        const overdueCount = activeCustomers.filter(c => c.nextVisitDate < today).length;
        const todayCount = activeCustomers.filter(c => c.nextVisitDate === today).length;
        
        document.getElementById('noticeBadge').textContent = overdueCount + todayCount;
        
        // 渲染通知列表
        const notificationList = document.getElementById('notificationList');
        const overdueCustomers = activeCustomers.filter(c => c.nextVisitDate < today).slice(0, 5);
        const todayCustomers = activeCustomers.filter(c => c.nextVisitDate === today).slice(0, 5);

        let html = '';
        
        if (overdueCustomers.length > 0) {
            html += `<div style="padding: 8px 0; font-weight: 600; color: #EF4444;">已过期 (${overdueCustomers.length})</div>`;
            overdueCustomers.forEach(c => {
                html += `
                    <div class="notification-item unread" onclick="app.showVisitModal('${c.id}')">
                        <div class="notification-item-title">${c.name}</div>
                        <div class="notification-item-desc">回访已过期，请尽快处理</div>
                        <div class="notification-item-time">下次回访: ${c.nextVisitDate}</div>
                    </div>
                `;
            });
        }

        if (todayCustomers.length > 0) {
            html += `<div style="padding: 8px 0; font-weight: 600; color: #F59E0B;">今日待回访 (${todayCustomers.length})</div>`;
            todayCustomers.forEach(c => {
                html += `
                    <div class="notification-item" onclick="app.showVisitModal('${c.id}')">
                        <div class="notification-item-title">${c.name}</div>
                        <div class="notification-item-desc">今日需要回访</div>
                        <div class="notification-item-time">电话: ${c.phone}</div>
                    </div>
                `;
            });
        }

        if (!html) {
            html = '<div class="empty-state"><p>暂无通知</p></div>';
        }

        notificationList.innerHTML = html;
    },

    closeNotificationPanel() {
        document.getElementById('notificationPanel').classList.remove('active');
    },

    // ==================== 客户管理 ====================
    async loadCustomers() {
        await this.renderCustomerTable();
    },

    async renderCustomerTable() {
        let customers = await this.getCustomers();
        const today = this.getDateString(new Date());
        
        // 搜索过滤
        const search = document.getElementById('customerSearch').value.trim().toLowerCase();
        if (search) {
            customers = customers.filter(c => 
                c.name.toLowerCase().includes(search) ||
                c.phone.includes(search) ||
                (c.company && c.company.toLowerCase().includes(search))
            );
        }

        // 等级过滤
        const levelFilter = document.getElementById('customerLevelFilter').value;
        if (levelFilter) {
            customers = customers.filter(c => c.level === levelFilter);
        }

        // 省份过滤
        const provinceFilter = document.getElementById('customerProvinceFilter')?.value;
        if (provinceFilter) {
            customers = customers.filter(c => c.province === provinceFilter);
        }
        
        // 城市过滤
        const cityFilter = document.getElementById('customerCityFilter')?.value;
        if (cityFilter) {
            customers = customers.filter(c => c.city === cityFilter);
        }

        // 状态过滤
        const statusFilter = document.getElementById('customerStatusFilter') ? document.getElementById('customerStatusFilter').value : '';
        if (statusFilter) {
            customers = customers.filter(c => c.status === statusFilter);
        }

        // 回访状态过滤
        const visitFilter = document.getElementById('customerVisitFilter') ? document.getElementById('customerVisitFilter').value : '';
        if (visitFilter === 'overdue') {
            customers = customers.filter(c => c.status === 'active' && c.nextVisitDate < today);
        } else if (visitFilter === 'today') {
            customers = customers.filter(c => c.status === 'active' && c.nextVisitDate === today);
        } else if (visitFilter === 'normal') {
            customers = customers.filter(c => !c.nextVisitDate || c.nextVisitDate > today);
        }

        // 分页
        const total = customers.length;
        const pageSize = this.currentPage.pageSize;
        const page = this.currentPage.customers;
        const start = (page - 1) * pageSize;
        const paginatedCustomers = customers.slice(start, start + pageSize);

        const tbody = document.getElementById('customerTableBody');
        
        if (paginatedCustomers.length === 0) {
            tbody.innerHTML = '<tr><td colspan="10" class="empty-state">暂无客户数据</td></tr>';
            return;
        }



        // 获取所有用户用于显示归属
        const users = await this.getAllUsers();

        tbody.innerHTML = paginatedCustomers.map(customer => {
            // 获取归属用户名称
            let ownerNames = '-';
            if (customer.ownerUsers && customer.ownerUsers.length > 0) {
                ownerNames = customer.ownerUsers
                    .map(uid => {
                        const u = users.find(user => user.id === uid);
                        return u ? u.realName : '';
                    })
                    .filter(name => name)
                    .join('、');
            }

            // 渲染客户标签
            let tagsHtml = '';
            if (customer.tags && customer.tags.length > 0) {
                const tagClassMap = {
                    '意向强烈': 'tag-intent',
                    '价格敏感': 'tag-price',
                    '决策周期长': 'tag-decision',
                    '长期合作': 'tag-cooperation',
                    '需重点跟进': 'tag-followup',
                    '已报价': 'tag-quoted'
                };
                tagsHtml = '<div class="customer-tags">' + 
                    customer.tags.map(tag => `<span class="tag ${tagClassMap[tag] || ''}">${tag}</span>`).join('') + 
                    '</div>';
            }

            // 判断是否需要回访
            const todayStr = this.getDateString(new Date());
            const isOverdue = customer.nextVisitDate && customer.nextVisitDate < todayStr && customer.status === 'active';
            const isTodayVisit = customer.nextVisitDate === todayStr && customer.status === 'active';
            const needsVisit = isOverdue || isTodayVisit;
            const visitBadge = isOverdue ? '<span style="color: var(--danger); margin-left: 4px;"><i class="fas fa-exclamation-circle"></i></span>' 
                             : (isTodayVisit ? '<span style="color: #F59E0B; margin-left: 4px;"><i class="fas fa-bell"></i></span>' : '');
            const rowStyle = isOverdue ? 'background: #FFF5F5;' : '';
            const isChecked = this.selectedCustomers.has(customer.id);

            return `
            <tr style="${rowStyle}">
                <td><input type="checkbox" class="customer-select-cb" data-id="${customer.id}" ${isChecked ? 'checked' : ''} onchange="app.toggleCustomerSelect('${customer.id}')"></td>
                <td>
                    <div style="display: flex; align-items: center; gap: 8px;">
                        <span class="level-tag ${customer.level}">${customer.level}</span>
                        <div>
                            <div>${customer.name}${visitBadge}</div>
                            ${tagsHtml}
                        </div>
                    </div>
                </td>
                <td>${customer.phone}</td>
                <td>${customer.company || '-'}</td>
                <td>${this.getLevelName(customer.level)}</td>
                <td><span class="region-tag">${customer.province || '-'} ${customer.city || ''}</span></td>
                <td><span style="color: var(--primary); font-weight: 500;">${ownerNames}</span></td>
                <td style="${isOverdue ? 'color:#EF4444;font-weight:600;' : (isTodayVisit ? 'color:#F59E0B;font-weight:600;' : '')}">${customer.nextVisitDate || '-'}${isOverdue ? ' <span style="background:#FEE2E2;color:#DC2626;padding:2px 6px;border-radius:4px;font-size:11px;">逾期</span>' : (isTodayVisit ? ' <span style="background:#FEF3C7;color:#D97706;padding:2px 6px;border-radius:4px;font-size:11px;">今日</span>' : '')}</td>
                <td><span class="status-tag ${customer.status}">${customer.status === 'active' ? '正常' : '已停用'}</span></td>
                <td class="actions">
                    <button class="btn-action" onclick="app.showCustomerDetail('${customer.id}')" title="查看">
                        <i class="fas fa-eye"></i>
                    </button>
                    <button class="btn-action" onclick="app.openCustomerModal('${customer.id}')" title="编辑">
                        <i class="fas fa-edit"></i>
                    </button>
                    <button class="btn-action ${needsVisit ? 'btn-urgent' : ''}" onclick="app.showVisitModal('${customer.id}')" title="回访" style="${isOverdue ? 'background: var(--danger); color: white;' : (isTodayVisit ? 'background:#F59E0B;color:white;' : '')}">
                        <i class="fas fa-phone"></i>
                    </button>
                    <button class="btn-action delete" onclick="app.deleteCustomer('${customer.id}')" title="删除">
                        <i class="fas fa-trash"></i>
                    </button>
                </td>
            </tr>
            `;
        }).join('');

        // 渲染分页
        this.renderPagination('customerPagination', total, pageSize, page, (newPage) => {
            this.currentPage.customers = newPage;
            this.renderCustomerTable();
        });

        // 渲染手机端卡片列表
        this.renderCustomerMobileList(paginatedCustomers, users);
    },

    // 渲染手机端客户卡片列表
    renderCustomerMobileList(customers, users) {
        const mobileList = document.getElementById('customerMobileList');
        if (!mobileList) return;

        if (customers.length === 0) {
            mobileList.innerHTML = '<div class="empty-state"><p>暂无客户数据</p></div>';
            return;
        }

        mobileList.innerHTML = customers.map(customer => {
            // 获取归属用户名称
            let ownerNames = '-';
            if (customer.ownerUsers && customer.ownerUsers.length > 0) {
                ownerNames = customer.ownerUsers
                    .map(uid => {
                        const u = users.find(user => user.id === uid);
                        return u ? u.realName : '';
                    })
                    .filter(n => n)
                    .join(', ');
            }

            // 判断回访状态
            const today = this.getDateString(new Date());
            const isOverdue = customer.status === 'active' && customer.nextVisitDate && customer.nextVisitDate < today;
            const isTodayVisit = customer.status === 'active' && customer.nextVisitDate === today;

            // 渲染客户标签
            let tagsHtml = '';
            if (customer.tags && customer.tags.length > 0) {
                const tagClassMap = {
                    '意向强烈': 'tag-intent',
                    '价格敏感': 'tag-price',
                    '决策周期长': 'tag-decision',
                    '长期合作': 'tag-cooperation',
                    '需重点跟进': 'tag-followup',
                    '已报价': 'tag-quoted'
                };
                tagsHtml = '<div class="customer-tags">' + 
                    customer.tags.map(tag => `<span class="tag ${tagClassMap[tag] || ''}">${tag}</span>`).join('') + 
                    '</div>';
            }

            return `
            <div class="customer-card">
                <div class="customer-card-header">
                    <div class="customer-card-title">
                        <span class="level-tag ${customer.level}">${customer.level}</span>
                        <h3>${customer.name}</h3>
                        ${isOverdue ? '<span style="color: var(--danger);"><i class="fas fa-bell"></i></span>' : ''}
                    </div>
                </div>
                <div class="customer-card-body">
                    <div class="info-row">
                        <span><i class="fas fa-phone"></i> ${customer.phone}</span>
                        <span class="region-tag">${customer.province || '-'} ${customer.city || ''}</span>
                    </div>
                    <div class="info-row">
                        <span><i class="fas fa-building"></i> ${customer.company || '-'}</span>
                    </div>
                    <div class="info-row">
                        <span><i class="fas fa-user"></i> ${ownerNames}</span>
                    </div>
                    <div class="info-row">
                        <span><i class="fas fa-calendar-alt"></i> 下次回访: ${customer.nextVisitDate || '-'}</span>
                        ${isOverdue ? '<span class="status-tag inactive">已逾期</span>' : (isTodayVisit ? '<span class="status-tag" style="background:#FEF3C7;color:#D97706;">今日</span>' : '')}
                    </div>
                    ${tagsHtml}
                </div>
                <div class="customer-card-footer">
                    <button class="btn btn-primary" onclick="app.showVisitModal('${customer.id}')">
                        <i class="fas fa-phone"></i> 回访
                    </button>
                    <button class="btn btn-secondary" onclick="app.showCustomerDetail('${customer.id}')">
                        <i class="fas fa-eye"></i> 查看
                    </button>
                    <button class="btn btn-secondary" onclick="app.openCustomerModal('${customer.id}')">
                        <i class="fas fa-edit"></i> 编辑
                    </button>
                </div>
            </div>
            `;
        }).join('');
    },

    renderPagination(elementId, total, pageSize, currentPage, onPageChange) {
        const totalPages = Math.ceil(total / pageSize);
        const el = document.getElementById(elementId);
        
        if (totalPages <= 1) {
            el.innerHTML = '';
            return;
        }

        let html = `<button ${currentPage === 1 ? 'disabled' : ''} onclick="app.currentPage.customers = ${currentPage - 1}; app.renderCustomerTable()">上一页</button>`;
        
        for (let i = 1; i <= totalPages; i++) {
            if (i === 1 || i === totalPages || (i >= currentPage - 1 && i <= currentPage + 1)) {
                html += `<button class="${i === currentPage ? 'active' : ''}" onclick="app.currentPage.customers = ${i}; app.renderCustomerTable()">${i}</button>`;
            } else if (i === currentPage - 2 || i === currentPage + 2) {
                html += `<button disabled>...</button>`;
            }
        }

        html += `<button ${currentPage === totalPages ? 'disabled' : ''} onclick="app.currentPage.customers = ${currentPage + 1}; app.renderCustomerTable()">下一页</button>`;
        
        el.innerHTML = html;
    },

    searchCustomers() {
        this.currentPage.customers = 1;
        this.renderCustomerTable();
    },

    // 省份筛选变化时动态加载城市
    onProvinceFilterChange() {
        const province = document.getElementById('customerProvinceFilter').value;
        const citySelect = document.getElementById('customerCityFilter');
        
        citySelect.innerHTML = '<option value="">全部城市</option>';
        
        if (!province) return;
        
        const cities = this.provinceCityData[province] || [];
        cities.forEach(city => {
            const option = document.createElement('option');
            option.value = city;
            option.textContent = city;
            citySelect.appendChild(option);
        });
    },

    filterCustomers() {
        this.currentPage.customers = 1;
        this.renderCustomerTable();
    },

    async openCustomerModal(customerId = null) {
        this.customerPhotos = [];
        document.getElementById('customerForm').reset();
        document.getElementById('customerId').value = '';
        document.getElementById('photoPreviewList').innerHTML = '';

        // 渲染归属用户选择
        await this.renderOwnerUsersSelect();
        
        // 加载经营范围选项
        await this.loadBusinessScopeCheckboxes();

        if (customerId) {
            const customers = await this.dbGetAll('customers');
            const customer = customers.find(c => c.id === customerId);
            if (customer) {
                document.getElementById('customerModalTitle').textContent = '编辑客户';
                document.getElementById('customerId').value = customer.id;
                document.getElementById('customerName').value = customer.name;
                document.getElementById('customerPhone').value = customer.phone;
                document.getElementById('customerCompany').value = customer.company || '';
                document.getElementById('customerLevel').value = customer.level;
                
                // 设置省市
                const provinceSelect = document.getElementById('customerProvince');
                const citySelect = document.getElementById('customerCity');
                if (provinceSelect) {
                    provinceSelect.value = customer.province || '河南省';
                    this.onProvinceChange();
                    if (citySelect) {
                        citySelect.value = customer.city || '';
                    }
                }
                
                document.getElementById('customerReturnDays').value = customer.returnVisitDays;
                document.getElementById('customerDetailAddress').value = customer.address || '';
                document.getElementById('customerRemark').value = customer.remark || '';
                
                // 经营范围
                document.querySelectorAll('input[name="businessScope"]').forEach(cb => {
                    cb.checked = customer.businessScope && customer.businessScope.includes(cb.value);
                });

                // 客户标签
                document.querySelectorAll('input[name="customerTag"]').forEach(cb => {
                    cb.checked = customer.tags && customer.tags.includes(cb.value);
                });

                // 归属用户
                if (customer.ownerUsers && customer.ownerUsers.length > 0) {
                    const checkboxes = document.querySelectorAll('.owner-user-checkbox');
                    checkboxes.forEach(cb => {
                        cb.checked = customer.ownerUsers.includes(cb.value);
                    });
                }

                // 照片
                if (customer.photos && customer.photos.length > 0) {
                    this.customerPhotos = [...customer.photos];
                    this.renderCustomerPhotos();
                }
            }
        } else {
            document.getElementById('customerModalTitle').textContent = '新增客户';
            document.getElementById('customerReturnDays').value = 30;
            // 新增时默认选中当前用户
            const checkboxes = document.querySelectorAll('.owner-user-checkbox');
            checkboxes.forEach(cb => {
                if (cb.value === this.currentUser.id) {
                    cb.checked = true;
                }
            });
        }

        this.openModal('customerModal');
    },

    // 渲染归属用户选择
    async renderOwnerUsersSelect() {
        // 获取所有用户（包括管理员自己）
        const users = await this.getAllUsers();
        const activeUsers = users.filter(u => u.status === 'active');
        const container = document.getElementById('ownerUsersSelect');
        
        if (activeUsers.length === 0) {
            container.innerHTML = '<span style="color:#999;">无可用用户</span>';
            return;
        }
        
        container.innerHTML = activeUsers.map(user => `
            <label class="owner-user-label">
                <input type="checkbox" class="owner-user-checkbox" value="${user.id}">
                <span>${user.realName || user.name}</span>
                ${user.role === 'admin' ? ' <span style="color:#667eea;">(管理员)</span>' : ''}
            </label>
        `).join('');
    },

    handlePhotoUpload(input) {
        if (input.files && input.files.length > 0) {
            const files = Array.from(input.files);
            const remaining = 5 - this.customerPhotos.length;
            
            if (remaining <= 0) {
                this.showToast('最多只能上传5张照片', 'warning');
                return;
            }

            const filesToProcess = files.slice(0, remaining);
            
            filesToProcess.forEach(file => {
                if (file.size > 5 * 1024 * 1024) {
                    this.showToast('单张照片不能超过5MB', 'warning');
                    return;
                }

                const reader = new FileReader();
                reader.onload = (e) => {
                    this.customerPhotos.push(e.target.result);
                    this.renderCustomerPhotos();
                };
                reader.readAsDataURL(file);
            });
        }
        input.value = '';
    },

    renderCustomerPhotos() {
        const container = document.getElementById('photoPreviewList');
        container.innerHTML = this.customerPhotos.map((photo, index) => `
            <div class="photo-preview">
                <img src="${photo}" alt="客户照片">
                <div class="photo-delete" onclick="app.deleteCustomerPhoto(${index})">
                    <i class="fas fa-times"></i>
                </div>
            </div>
        `).join('');
    },

    deleteCustomerPhoto(index) {
        this.customerPhotos.splice(index, 1);
        this.renderCustomerPhotos();
    },

    // 下载导入客户数据模板
    downloadImportTemplate() {
        try {
            // 表头定义
            const headers = ['姓名', '电话', '公司', '等级', '省份', '城市', '详细地址', '回访周期(天)', '经营范围', '客户标签', '下次回访日期', '状态', '备注'];
            
            // 示例数据（演示格式）
            const exampleData = [
                {
                    '姓名': '张三',
                    '电话': '13800138001',
                    '公司': '某某公司',
                    '等级': 'A',
                    '省份': '河南省',
                    '城市': '郑州市',
                    '详细地址': '金水区某某路123号',
                    '回访周期(天)': '30',
                    '经营范围': '建材',
                    '客户标签': '重点客户',
                    '下次回访日期': '2026-04-01',
                    '状态': '正常',
                    '备注': '这是示例数据，请删除后填写自己的数据'
                },
                {
                    '姓名': '李四',
                    '电话': '13900139002',
                    '公司': '某某企业',
                    '等级': 'B',
                    '省份': '河南省',
                    '城市': '洛阳市',
                    '详细地址': '涧西区某某街456号',
                    '回访周期(天)': '60',
                    '经营范围': '电子产品',
                    '客户标签': '潜在客户',
                    '下次回访日期': '2026-05-01',
                    '状态': '正常',
                    '备注': ''
                }
            ];

            // 创建工作簿
            const wb = XLSX.utils.book_new();

            // 创建示例数据工作表
            const ws = XLSX.utils.json_to_sheet(exampleData, { header: headers });

            // 设置列宽
            const colWidths = [
                { wch: 10 }, { wch: 15 }, { wch: 20 }, { wch: 8 },
                { wch: 12 }, { wch: 12 }, { wch: 30 }, { wch: 12 },
                { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 8 }, { wch: 30 }
            ];
            ws['!cols'] = colWidths;

            // 添加工作表
            XLSX.utils.book_append_sheet(wb, ws, '客户数据导入模板');

            // 生成文件并下载
            XLSX.writeFile(wb, '客户数据导入模板.xlsx');
            
            this.showToast('模板已下载', 'success');
        } catch (e) {
            console.error('模板下载失败:', e);
            this.showToast('模板下载失败: ' + e.message, 'error');
        }
    },

    // 导出客户数据(Excel格式 - 使用SheetJS)
    async exportCustomersExcel() {
        // 权限检查
        if (!await this.hasPermission('data.export')) {
            this.showToast('您没有导出数据的权限', 'error');
            return;
        }

        const customers = await this.getCustomers();
        const users = await this.getAllUsers();

        if (customers.length === 0) {
            this.showToast('没有可导出的数据', 'warning');
            return;
        }

        try {
            // 准备Excel数据
            const headers = ['姓名', '电话', '公司', '等级', '省份', '城市', '详细地址', '回访周期(天)', '经营范围', '客户标签', '下次回访日期', '状态', '备注', '归属用户', '创建时间'];
            const rows = customers.map(c => {
                // 获取用户名称
                const ownerUserNames = c.ownerUsers && c.ownerUsers.length > 0
                    ? c.ownerUsers.map(uid => {
                        const user = users.find(u => u.id === uid);
                        return user ? user.realName : '';
                    }).filter(Boolean).join('、')
                    : '';

                return {
                    '姓名': c.name,
                    '电话': c.phone,
                    '公司': c.company || '',
                    '等级': this.getLevelName(c.level),
                    '省份': c.province || '',
                    '城市': c.city || '',
                    '详细地址': c.address || '',
                    '回访周期(天)': c.returnVisitDays || 30,
                    '经营范围': c.businessScope && c.businessScope.length > 0 ? c.businessScope.join('、') : '',
                    '客户标签': c.tags && c.tags.length > 0 ? c.tags.join('、') : '',
                    '下次回访日期': c.nextVisitDate || '',
                    '状态': c.status === 'active' ? '正常' : '已停用',
                    '备注': c.remark || '',
                    '归属用户': ownerUserNames,
                    '创建时间': c.createdAt ? new Date(c.createdAt).toLocaleString('zh-CN') : ''
                };
            });

            // 创建工作簿
            const wb = XLSX.utils.book_new();

            // 创建工作表
            const ws = XLSX.utils.json_to_sheet(rows, { header: headers });

            // 设置列宽
            const colWidths = [
                { wch: 10 }, // 姓名
                { wch: 15 }, // 电话
                { wch: 20 }, // 公司
                { wch: 8 },  // 等级
                { wch: 12 }, // 省份
                { wch: 12 }, // 城市
                { wch: 30 }, // 详细地址
                { wch: 12 }, // 回访周期
                { wch: 20 }, // 经营范围
                { wch: 20 }, // 客户标签
                { wch: 15 }, // 下次回访日期
                { wch: 8 },  // 状态
                { wch: 30 }, // 备注
                { wch: 20 }, // 归属用户
                { wch: 20 }  // 创建时间
            ];
            ws['!cols'] = colWidths;

            // 添加工作表到工作簿
            XLSX.utils.book_append_sheet(wb, ws, '客户数据');

            // 生成Excel文件并下载
            const fileName = `客户数据_${this.getDateString(new Date())}.xlsx`;
            XLSX.writeFile(wb, fileName);

            this.showToast('Excel文件导出成功', 'success');
        } catch (e) {
            console.error('Excel导出失败:', e);
            this.showToast('Excel导出失败: ' + e.message, 'error');
        }
    },

    // 导出客户数据(CSV格式)
    async exportCustomersCSV() {
        // 权限检查
        if (!await this.hasPermission('data.export')) {
            this.showToast('您没有导出数据的权限', 'error');
            return;
        }

        const customers = await this.getCustomers();
        const users = await this.getAllUsers();

        if (customers.length === 0) {
            this.showToast('没有可导出的数据', 'warning');
            return;
        }

        // 生成CSV内容
        const headers = ['姓名', '电话', '公司', '等级', '省份', '城市', '详细地址', '回访周期(天)', '经营范围', '客户标签', '下次回访日期', '状态', '备注', '归属用户', '创建时间'];
        const rows = customers.map(c => {
            // 获取用户名称
            const ownerUserNames = c.ownerUsers && c.ownerUsers.length > 0
                ? c.ownerUsers.map(uid => {
                    const user = users.find(u => u.id === uid);
                    return user ? user.realName : '';
                }).filter(Boolean).join('、')
                : '';

            return [
                c.name,
                c.phone,
                c.company || '',
                this.getLevelName(c.level),
                c.province || '',
                c.city || '',
                c.address || '',
                c.returnVisitDays || 30,
                c.businessScope && c.businessScope.length > 0 ? c.businessScope.join('、') : '',
                c.tags && c.tags.length > 0 ? c.tags.join('、') : '',
                c.nextVisitDate || '',
                c.status === 'active' ? '正常' : '已停用',
                c.remark || '',
                ownerUserNames,
                c.createdAt ? new Date(c.createdAt).toLocaleString('zh-CN') : ''
            ];
        });

        // 创建CSV内容
        let csvContent = '\ufeff'; // BOM for UTF-8
        csvContent += headers.join(',') + '\n';

        rows.forEach(row => {
            csvContent += row.map(cell => `"${(cell || '').toString().replace(/"/g, '""')}"`).join(',') + '\n';
        });

        // 下载文件
        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `客户数据_${this.getDateString(new Date())}.csv`;
        link.click();
        URL.revokeObjectURL(url);

        this.showToast('CSV文件导出成功', 'success');
    },

    async saveCustomer() {
        try {
            const id = document.getElementById('customerId').value;
            const name = document.getElementById('customerName').value.trim();
            const phone = document.getElementById('customerPhone').value.trim();
            
            if (!name || !phone) {
                this.showToast('请填写姓名和电话', 'error');
                return;
            }

            // 收集经营范围
            const businessScope = [];
            document.querySelectorAll('input[name="businessScope"]:checked').forEach(cb => {
                businessScope.push(cb.value);
            });

            // 收集客户标签
            const tags = [];
            document.querySelectorAll('input[name="customerTag"]:checked').forEach(cb => {
                tags.push(cb.value);
            });

            // 收集归属用户
            let ownerUsers = [];
            document.querySelectorAll('.owner-user-checkbox:checked').forEach(cb => {
                ownerUsers.push(cb.value);
            });

            // 如果没有选择归属用户，默认归属给当前用户（如果是管理员则包含所有可用用户）
            if (ownerUsers.length === 0) {
                if (this.currentUser) {
                    if (this.currentUser.role === 'admin') {
                        // 管理员：获取所有可用用户
                        const assignableUsers = await this.getAssignableUsers();
                        ownerUsers = assignableUsers.map(u => u.id);
                        if (ownerUsers.length === 0) {
                            // 没有其他用户，默认归属给当前管理员
                            ownerUsers = [this.currentUser.id];
                        }
                    } else {
                        // 非管理员：默认归属给自己
                        ownerUsers = [this.currentUser.id];
                    }
                }
            }

            const province = document.getElementById('customerProvince').value;
            const city = document.getElementById('customerCity').value;
            
            if (!province || !city) {
                this.showToast('请选择省份和城市', 'warning');
                return;
            }
            
            const customerData = {
                name,
                phone,
                company: document.getElementById('customerCompany').value.trim(),
                level: document.getElementById('customerLevel').value,
                province: province,
                city: city,
                returnVisitDays: parseInt(document.getElementById('customerReturnDays').value) || 30,
                address: document.getElementById('customerDetailAddress').value.trim(),
                remark: document.getElementById('customerRemark').value.trim(),
                businessScope,
                tags,
                photos: this.customerPhotos,
                ownerUsers,
                updatedAt: new Date().toISOString()
            };

            const customers = await this.dbGetAll('customers');

            if (id) {
                // 编辑
                const index = customers.findIndex(c => c.id === id);
                if (index !== -1) {
                    customers[index] = { ...customers[index], ...customerData };
                    await this.dbPut('customers', customers[index]);
                }
            } else {
                // 新增
                const now = new Date();
                const newCustomer = {
                    id: this.generateId(),
                    ...customerData,
                    lastVisitDate: null,
                    nextVisitDate: this.getDateString(now),
                    stage: '初次接触',
                    status: 'active',
                    createdAt: new Date().toISOString()
                };
                await this.dbPut('customers', newCustomer);
            }

            this.closeModal('customerModal');
            this.showToast('客户信息已保存', 'success');
            await this.loadCustomers();
            
            if (document.getElementById('pageDashboard').classList.contains('active')) {
                await this.loadDashboard();
            }
        } catch (e) {
            console.error('保存客户失败:', e);
            this.showToast('保存失败: ' + e.message, 'error');
        }
    },

    async deleteCustomer(id) {
        // 权限检查：需要客户删除权限
        if (!await this.hasPermission('customer.delete')) {
            this.showToast('您没有删除客户的权限', 'error');
            return;
        }
        
        this.showConfirm('删除客户', '确定要删除该客户吗？此操作不可恢复！', async () => {
            await this.dbDelete('customers', id);
            await this.loadCustomers();
            
            if (document.getElementById('pageDashboard').classList.contains('active')) {
                await this.loadDashboard();
            }
            this.showToast('客户已删除', 'success');
        }, 'danger');
    },

    async showCustomerDetail(customerId) {
        const customers = await this.dbGetAll('customers');
        const customer = customers.find(c => c.id === customerId);
        
        if (!customer) return;

        const regionNames = {
            core: '郑州核心区',
            othercity: '河南省内其他城市',
            domestic: '国内其他省份',
            overseas: '海外'
        };

        // 获取归属用户名称
        const users = await this.getAllUsers();
        let ownerNames = '-';
        if (customer.ownerUsers && customer.ownerUsers.length > 0) {
            ownerNames = customer.ownerUsers
                .map(uid => {
                    const u = users.find(user => user.id === uid);
                    return u ? u.realName : '';
                })
                .filter(name => name)
                .join('、');
        }

        document.getElementById('detailName').textContent = customer.name;
        document.getElementById('detailPhone').textContent = customer.phone;
        document.getElementById('detailCompany').textContent = customer.company || '-';
        document.getElementById('detailLevel').textContent = this.getLevelName(customer.level);
        document.getElementById('detailBusinessScope').textContent = customer.businessScope ? customer.businessScope.join('、') : '-';
        document.getElementById('detailAddress').textContent = customer.address || '-';
        document.getElementById('detailRemark').textContent = customer.remark || '-';
        document.getElementById('detailNextVisit').textContent = customer.nextVisitDate || '-';
        document.getElementById('detailOwnerUsers').textContent = ownerNames;

        // 照片
        const photosEl = document.getElementById('detailPhotos');
        if (customer.photos && customer.photos.length > 0) {
            photosEl.innerHTML = customer.photos.map(photo => `<img src="${photo}" alt="客户照片">`).join('');
        } else {
            photosEl.innerHTML = '<div class="empty-state"><p>暂无照片</p></div>';
        }

        // 渲染跟进时间线
        await this.renderCustomerTimeline(customerId);

        // 存储当前查看的客户ID
        this.currentDetailCustomerId = customerId;

        this.openModal('customerDetailModal');
    },

    editCustomerFromDetail() {
        this.closeModal('customerDetailModal');
        this.openCustomerModal(this.currentDetailCustomerId);
    },

    // ==================== 客户跟进时间线 ====================
    async renderCustomerTimeline(customerId) {
        const el = document.getElementById('customerTimeline');
        if (!el) return;

        const visitRecords = await this.dbGetAll('visit_records');
        const customerVisits = visitRecords
            .filter(r => r.customerId === customerId)
            .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

        if (customerVisits.length === 0) {
            el.innerHTML = '<div style="text-align:center;color:#9ca3af;padding:20px;font-size:13px;"><i class="fas fa-inbox" style="font-size:24px;display:block;margin-bottom:8px;"></i>暂无跟进记录</div>';
            return;
        }

        const methodIcons = {
            '电话': 'fa-phone', '微信': 'fa-weixin', '上门拜访': 'fa-map-marker-alt',
            '邮件': 'fa-envelope', '视频通话': 'fa-video', '其他': 'fa-comment'
        };
        const methodColors = {
            '电话': '#4F46E5', '微信': '#10B981', '上门拜访': '#F59E0B',
            '邮件': '#EF4444', '视频通话': '#8B5CF6', '其他': '#6B7280'
        };
        const stageColors = {
            '初次接触': '#E0F2FE', '需求了解': '#FEF3C7', '产品介绍': '#D1FAE5',
            '异议处理': '#FEE2E2', '签约': '#DCFCE7', '售后服务': '#EDE9FE', '其他': '#F3F4F6'
        };

        el.innerHTML = `<div style="position:relative;padding-left:28px;">
            <div style="position:absolute;left:10px;top:0;bottom:0;width:2px;background:linear-gradient(to bottom,#4F46E5,#E5E7EB);border-radius:2px;"></div>
            ${customerVisits.map((r, idx) => {
                const icon = methodIcons[r.method] || 'fa-comment';
                const color = methodColors[r.method] || '#6B7280';
                const stageBg = stageColors[r.stage] || '#F3F4F6';
                const dateStr = r.createdAt ? new Date(r.createdAt).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }) : '-';
                const stars = r.satisfaction ? '★'.repeat(r.satisfaction) + '☆'.repeat(5 - r.satisfaction) : '';
                return `
                    <div style="position:relative;margin-bottom:16px;background:#fff;border:1px solid #f3f4f6;border-radius:10px;padding:12px 14px;box-shadow:0 1px 3px rgba(0,0,0,0.05);">
                        <div style="position:absolute;left:-22px;top:12px;width:24px;height:24px;border-radius:50%;background:${color};display:flex;align-items:center;justify-content:center;box-shadow:0 0 0 3px #fff,0 0 0 5px ${color}30;">
                            <i class="fas ${icon}" style="font-size:10px;color:#fff;"></i>
                        </div>
                        <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;flex-wrap:wrap;">
                            <span style="font-size:12px;color:#9ca3af;">${dateStr}</span>
                            <span style="font-size:11px;padding:2px 8px;border-radius:10px;background:${color}20;color:${color};font-weight:600;">${r.method || '其他'}</span>
                            ${r.stage ? `<span style="font-size:11px;padding:2px 8px;border-radius:10px;background:${stageBg};color:#374151;">${r.stage}</span>` : ''}
                            ${stars ? `<span style="font-size:11px;color:#F59E0B;letter-spacing:1px;">${stars}</span>` : ''}
                        </div>
                        ${r.content ? `<div style="font-size:13px;color:#374151;line-height:1.5;margin-bottom:4px;">${r.content}</div>` : ''}
                        ${r.result ? `<div style="font-size:12px;color:#6b7280;padding:6px 10px;background:#f9fafb;border-radius:6px;border-left:3px solid ${color};">跟进结果：${r.result}</div>` : ''}
                    </div>
                `;
            }).join('')}
        </div>`;
    },


    async printCustomerReport() {
        if (!this.currentDetailCustomerId) return;

        const customers = await this.dbGetAll('customers');
        const customer = customers.find(c => c.id === this.currentDetailCustomerId);
        if (!customer) return;

        const users = await this.getAllUsers();
        const ownerNames = (customer.ownerUsers || [])
            .map(uid => { const u = users.find(u => u.id === uid); return u ? u.realName : ''; })
            .filter(Boolean).join('、') || '-';

        const visitRecords = await this.dbGetAll('visit_records');
        const customerVisits = visitRecords
            .filter(r => r.customerId === this.currentDetailCustomerId)
            .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

        const levelColors = { A: '#DC2626', B: '#2563EB', C: '#16A34A', D: '#9CA3AF' };
        const levelColor = levelColors[customer.level] || '#6B7280';
        const levelName = this.getLevelName(customer.level);

        const photosHtml = customer.photos && customer.photos.length > 0
            ? customer.photos.map(p => `<img src="${p}" style="width:100px;height:80px;object-fit:cover;border-radius:6px;border:1px solid #e5e7eb;" />`).join('')
            : '<span style="color:#9ca3af;font-size:13px;">暂无照片</span>';

        const visitsHtml = customerVisits.length === 0
            ? '<tr><td colspan="5" style="text-align:center;color:#9ca3af;padding:16px;">暂无回访记录</td></tr>'
            : customerVisits.slice(0, 10).map(r => `
                <tr>
                    <td style="padding:8px;border-bottom:1px solid #f3f4f6;">${r.createdAt ? r.createdAt.split('T')[0] : '-'}</td>
                    <td style="padding:8px;border-bottom:1px solid #f3f4f6;">${r.method || '-'}</td>
                    <td style="padding:8px;border-bottom:1px solid #f3f4f6;">${r.stage || '-'}</td>
                    <td style="padding:8px;border-bottom:1px solid #f3f4f6;">${r.satisfaction ? '★'.repeat(r.satisfaction) : '-'}</td>
                    <td style="padding:8px;border-bottom:1px solid #f3f4f6;max-width:200px;word-break:break-all;">${r.content || '-'}</td>
                </tr>
            `).join('');

        const reportHtml = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>客户报告 - ${customer.name}</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; color: #1f2937; padding: 32px; font-size: 14px; }
  .header { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 2px solid #4F46E5; padding-bottom: 16px; margin-bottom: 24px; }
  .header-left h1 { font-size: 22px; color: #1f2937; margin-bottom: 4px; }
  .header-left p { color: #6b7280; font-size: 13px; }
  .header-right { text-align: right; color: #6b7280; font-size: 12px; }
  .section { margin-bottom: 24px; }
  .section-title { font-size: 15px; font-weight: 700; color: #4F46E5; border-left: 4px solid #4F46E5; padding-left: 10px; margin-bottom: 14px; }
  .info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .info-item { background: #f9fafb; padding: 10px 14px; border-radius: 8px; }
  .info-item .label { color: #9ca3af; font-size: 12px; margin-bottom: 4px; }
  .info-item .value { font-weight: 600; color: #1f2937; font-size: 14px; }
  .level-badge { display: inline-block; padding: 3px 12px; border-radius: 20px; font-size: 13px; font-weight: 700; background: ${levelColor}20; color: ${levelColor}; border: 1px solid ${levelColor}40; }
  .photos-wrap { display: flex; gap: 10px; flex-wrap: wrap; }
  table { width: 100%; border-collapse: collapse; font-size: 13px; }
  th { background: #f3f4f6; padding: 10px 8px; text-align: left; color: #6b7280; font-weight: 600; }
  td { padding: 8px; border-bottom: 1px solid #f3f4f6; }
  .print-footer { margin-top: 32px; text-align: center; color: #9ca3af; font-size: 12px; border-top: 1px solid #e5e7eb; padding-top: 16px; }
  @media print { body { padding: 16px; } }
</style>
</head>
<body>
  <div class="header">
    <div class="header-left">
      <h1><i>客户档案报告</i></h1>
      <p>${customer.name} · ${customer.company || ''} · ${ownerNames}</p>
    </div>
    <div class="header-right">
      <div>导出时间：${new Date().toLocaleString('zh-CN')}</div>
      <div>客户等级：<span class="level-badge">${levelName}级</span></div>
    </div>
  </div>

  <div class="section">
    <div class="section-title">基本信息</div>
    <div class="info-grid">
      <div class="info-item"><div class="label">姓名</div><div class="value">${customer.name}</div></div>
      <div class="info-item"><div class="label">联系电话</div><div class="value">${customer.phone}</div></div>
      <div class="info-item"><div class="label">公司/单位</div><div class="value">${customer.company || '-'}</div></div>
      <div class="info-item"><div class="label">客户等级</div><div class="value"><span class="level-badge">${levelName}级</span></div></div>
      <div class="info-item"><div class="label">所在省份</div><div class="value">${customer.province || '-'}</div></div>
      <div class="info-item"><div class="label">所在城市</div><div class="value">${customer.city || '-'}</div></div>
      <div class="info-item"><div class="label">详细地址</div><div class="value">${customer.address || '-'}</div></div>
      <div class="info-item"><div class="label">回访周期</div><div class="value">${customer.returnVisitDays || 30} 天</div></div>
      <div class="info-item"><div class="label">下次回访日期</div><div class="value" style="color:#4F46E5;">${customer.nextVisitDate || '-'}</div></div>
      <div class="info-item"><div class="label">归属用户</div><div class="value">${ownerNames}</div></div>
      <div class="info-item" style="grid-column:1/-1;"><div class="label">经营范围</div><div class="value">${customer.businessScope && customer.businessScope.length ? customer.businessScope.join('、') : '-'}</div></div>
      <div class="info-item" style="grid-column:1/-1;"><div class="label">客户标签</div><div class="value">${customer.tags && customer.tags.length ? customer.tags.map(t => `<span style="background:#EEF2FF;color:#4F46E5;padding:2px 8px;border-radius:12px;font-size:12px;margin-right:4px;">${t}</span>`).join('') : '-'}</div></div>
      <div class="info-item" style="grid-column:1/-1;"><div class="label">备注</div><div class="value">${customer.remark || '-'}</div></div>
    </div>
  </div>

  ${customer.photos && customer.photos.length > 0 ? `
  <div class="section">
    <div class="section-title">客户照片</div>
    <div class="photos-wrap">${photosHtml}</div>
  </div>` : ''}

  <div class="section">
    <div class="section-title">回访记录（最近10条）</div>
    <table>
      <thead><tr>
        <th>日期</th><th>方式</th><th>阶段</th><th>满意度</th><th>内容摘要</th>
      </tr></thead>
      <tbody>${visitsHtml}</tbody>
    </table>
  </div>

  <div class="print-footer">
    客户回访登记系统 · 本报告由系统自动生成 · ${new Date().toLocaleDateString('zh-CN')}
  </div>
</body>
</html>`;

        // 打开新窗口并打印
        const printWindow = window.open('', '_blank', 'width=900,height=700');
        if (!printWindow) {
            this.showToast('请允许弹出窗口以打印报告', 'warning');
            return;
        }
        printWindow.document.write(reportHtml);
        printWindow.document.close();
        printWindow.onload = () => {
            printWindow.print();
        };
    },


    async showVisitModal(customerId) {
        const customers = await this.dbGetAll('customers');
        const customer = customers.find(c => c.id === customerId);
        
        if (!customer) return;

        // 权限检查：非管理员只能查看自己名下的客户
        if (this.currentUser.role !== 'admin') {
            if (!customer.ownerUsers || !customer.ownerUsers.includes(this.currentUser.id)) {
                this.showToast('您没有权限查看此客户的回访记录', 'error');
                return;
            }
        }

        this.currentVisitCustomerId = customerId;

        document.getElementById('visitCustomerName').textContent = customer.name;
        document.getElementById('visitCustomerPhone').textContent = customer.phone;
        document.getElementById('visitCustomerCompany').textContent = customer.company || '-';
        document.getElementById('visitCustomerLevel').textContent = this.getLevelName(customer.level);

        // 设置下次回访日期默认值
        const nextDate = new Date();
        nextDate.setDate(nextDate.getDate() + (customer.returnVisitDays || 30));
        document.getElementById('nextVisitDate').value = this.getDateString(nextDate);
        document.getElementById('visitStage').value = customer.stage || '初次接触';

        // 加载历史回访记录
        await this.loadVisitHistory(customerId);

        this.closeNotificationPanel();
        this.openModal('visitModal');
    },

    async loadVisitHistory(customerId) {
        this.currentVisitCustomerId = customerId;
        const records = await this.dbGetAll('visit_records');
        const customerRecords = records.filter(r => r.customerId === customerId).sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

        // 保存原始数据用于过滤
        this.currentVisitRecords = customerRecords;

        this.renderVisitHistory(customerRecords);
    },

    // 渲染回访历史记录
    renderVisitHistory(records) {
        const listEl = document.getElementById('visitHistoryList');

        if (records.length === 0) {
            listEl.innerHTML = '<div class="empty-state"><p>暂无回访记录</p></div>';
            return;
        }

        listEl.innerHTML = records.map(record => {
            // 渲染满意度星星
            let satisfactionStars = '';
            if (record.satisfaction && record.satisfaction > 0) {
                satisfactionStars = '<span style="color: #F59E0B;">' +
                    Array(record.satisfaction).fill('<i class="fas fa-star"></i>').join('') +
                    '</span>';
            }

            // 回访方式图标
            const methodIcons = {
                '电话': '<i class="fas fa-phone"></i>',
                '微信': '<i class="fab fa-weixin"></i>',
                '上门拜访': '<i class="fas fa-walking"></i>',
                '邮件': '<i class="fas fa-envelope"></i>',
                '视频通话': '<i class="fas fa-video"></i>'
            };
            const methodIcon = methodIcons[record.method] || '<i class="fas fa-comment"></i>';

            return `
            <div class="visit-history-item">
                <div class="visit-history-header">
                    <span class="visit-history-stage">${methodIcon} ${record.stage}</span>
                    <span class="visit-history-date">${record.createdAt.split('T')[0]} ${satisfactionStars}</span>
                </div>
                ${record.content ? `<div class="visit-history-content">${record.content}</div>` : ''}
                ${record.result ? `<div class="visit-history-result">结果: ${record.result}</div>` : ''}
            </div>
            `;
        }).join('');
    },

    // 过滤回访历史记录
    filterVisitHistory() {
        if (!this.currentVisitRecords) return;

        const searchKeyword = document.getElementById('visitHistorySearch').value.trim().toLowerCase();
        const methodFilter = document.getElementById('visitMethodFilter').value;
        const stageFilter = document.getElementById('visitStageFilter').value;

        let filtered = this.currentVisitRecords;

        // 关键词搜索
        if (searchKeyword) {
            filtered = filtered.filter(record => {
                const content = (record.content || '').toLowerCase();
                const result = (record.result || '').toLowerCase();
                return content.includes(searchKeyword) || result.includes(searchKeyword);
            });
        }

        // 方式过滤
        if (methodFilter) {
            filtered = filtered.filter(record => record.method === methodFilter);
        }

        // 阶段过滤
        if (stageFilter) {
            filtered = filtered.filter(record => record.stage === stageFilter);
        }

        this.renderVisitHistory(filtered);
    },

    // 加载当前阶段的话术（回访时显示）
    async loadStageScripts() {
        const stage = document.getElementById('visitStage').value;
        const scripts = await this.dbGetAll('scripts');
        const stageScripts = scripts.filter(s => s.stage === stage);
        
        const container = document.getElementById('stageScriptsContainer');
        const list = document.getElementById('stageScriptsList');
        
        if (stageScripts.length === 0) {
            list.innerHTML = '<div style="color:#999;text-align:center;padding:10px;">暂无话术，请添加</div>';
            container.style.display = 'block';
            return;
        }
        
        list.innerHTML = stageScripts.map(script => `
            <div style="padding:8px;margin-bottom:8px;background:white;border-radius:6px;cursor:pointer;border:1px solid #eee;" 
                 onclick="app.copyScript('${script.id}')" title="点击复制">
                <div style="font-weight:600;font-size:13px;color:#333;">${script.title}</div>
                <div style="font-size:12px;color:#666;margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${script.content}</div>
            </div>
        `).join('');
        
        container.style.display = 'block';
    },

    // 复制话术内容
    copyScript(scriptId) {
        const scripts = this.dbGetAll('scripts').then(allScripts => {
            const script = allScripts.find(s => s.id === scriptId);
            if (script) {
                navigator.clipboard.writeText(script.content).then(() => {
                    this.showToast('话术已复制到剪贴板', 'success');
                }).catch(() => {
                    // 兼容旧浏览器
                    const textarea = document.createElement('textarea');
                    textarea.value = script.content;
                    document.body.appendChild(textarea);
                    textarea.select();
                    document.execCommand('copy');
                    document.body.removeChild(textarea);
                    this.showToast('话术已复制到剪贴板', 'success');
                });
                
                // 自动填充到回访内容
                document.getElementById('visitContent').value = script.content;
            }
        });
    },

    async saveVisitRecord() {
        const customerId = this.currentVisitCustomerId;
        const method = document.getElementById('visitMethod').value;
        const stage = document.getElementById('visitStage').value;
        const satisfaction = parseInt(document.getElementById('visitSatisfaction').value) || 0;
        const content = document.getElementById('visitContent').value.trim();
        const result = document.getElementById('visitResult').value.trim();
        const nextVisitDate = document.getElementById('nextVisitDate').value;

        const recordData = {
            customerId,
            method,
            stage,
            satisfaction,
            content,
            result,
            nextVisitDate,
            operator: this.currentUser.realName,
            createdAt: new Date().toISOString()
        };

        // 保存记录
        const newRecord = {
            id: this.generateId(),
            ...recordData
        };
        await this.dbPut('visit_records', newRecord);

        // 更新客户信息
        const customers = await this.dbGetAll('customers');
        const customerIndex = customers.findIndex(c => c.id === customerId);
        
        if (customerIndex !== -1) {
            customers[customerIndex].stage = stage;
            customers[customerIndex].lastVisitDate = this.getDateString(new Date());
            if (nextVisitDate) {
                customers[customerIndex].nextVisitDate = nextVisitDate;
            }
            customers[customerIndex].updatedAt = new Date().toISOString();
            await this.dbPut('customers', customers[customerIndex]);
        }
        
        // 清空表单
        document.getElementById('visitContent').value = '';
        document.getElementById('visitResult').value = '';
        document.getElementById('visitSatisfaction').value = '0';
        document.querySelectorAll('.rating-star').forEach(star => star.classList.remove('active'));

        // 刷新历史记录
        await this.loadVisitHistory(customerId);

        // 刷新当前页面
        if (document.getElementById('pageDashboard').classList.contains('active')) {
            await this.loadDashboard();
        }
        if (document.getElementById('pageCustomers').classList.contains('active')) {
            await this.loadCustomers();
        }

        this.showToast('回访记录已保存', 'success');
    },

    // ==================== 客户分类 ====================
    async loadClassify() {
        await this.renderLevelSettings();
        await this.renderBusinessScopeSettings();
    },

    async renderLevelSettings() {
        let settings = await this.dbGet('settings', 'main');
        if (!settings) {
            settings = { id: 'main', levelSettings: {
                A: { days: 7, name: '重点客户' },
                B: { days: 15, name: '重要客户' },
                C: { days: 30, name: '普通客户' },
                D: { days: 60, name: '潜在客户' }
            }};
            await this.dbPut('settings', settings);
        }
        
        const levelSettings = settings.levelSettings || {
            A: { days: 7, name: '重点客户' },
            B: { days: 15, name: '重要客户' },
            C: { days: 30, name: '普通客户' },
            D: { days: 60, name: '潜在客户' }
        };

        const html = ['A', 'B', 'C', 'D'].map(level => `
            <div class="level-item">
                <div class="level-item-info">
                    <span class="level-tag ${level}">${level}</span>
                    <span>${levelSettings[level].name}</span>
                </div>
                <div class="level-item-days">
                    <input type="number" value="${levelSettings[level].days}" min="1" id="levelDays${level}">
                    <span>天/次</span>
                    <button class="btn btn-sm btn-primary" onclick="app.saveLevelSettings('${level}')">保存</button>
                </div>
            </div>
        `).join('');

        document.getElementById('levelSettings').innerHTML = html;
    },

    async saveLevelSettings(level) {
        const days = parseInt(document.getElementById('levelDays' + level).value);
        
        let settings = await this.dbGet('settings', 'main');
        if (!settings) {
            settings = { id: 'main' };
        }
        
        settings.levelSettings = settings.levelSettings || {
            A: { days: 7, name: '重点客户' },
            B: { days: 15, name: '重要客户' },
            C: { days: 30, name: '普通客户' },
            D: { days: 60, name: '潜在客户' }
        };
        settings.levelSettings[level].days = days;
        
        await this.dbPut('settings', settings);
        this.showToast('设置已保存', 'success');
    },

    // 渲染经营范围设置
    async renderBusinessScopeSettings() {
        const settings = await this.dbGet('settings', 'main');
        const scopes = settings?.businessScopes || ['建材', '电子产品', '服装', '食品', '服务业', '其他'];

        const html = scopes.map((scope, index) => `
            <div class="region-item">
                <div class="region-item-info">
                    <strong>${scope}</strong>
                </div>
                <div>
                    <button class="btn-action" onclick="app.editBusinessScope('${scope}', ${index})" title="修改" style="color: #3B82F6;margin-right:8px;">
                        <i class="fas fa-edit"></i>
                    </button>
                    <button class="btn-action" onclick="app.deleteBusinessScope('${scope}')" title="删除" style="color: #EF4444;">
                        <i class="fas fa-trash"></i>
                    </button>
                </div>
            </div>
        `).join('');

        document.getElementById('businessScopeSettings').innerHTML = html;
    },

    // 打开经营范围模态框
    openBusinessScopeModal() {
        document.getElementById('businessScopeName').value = '';
        document.getElementById('businessScopeModal').classList.add('active');
    },

    // 保存经营范围
    async saveBusinessScope() {
        const name = document.getElementById('businessScopeName').value.trim();
        if (!name) {
            this.showToast('请输入经营范围名称', 'warning');
            return;
        }

        const settings = await this.dbGet('settings', 'main') || { id: 'main' };
        if (!settings.businessScopes) {
            settings.businessScopes = ['建材', '电子产品', '服装', '食品', '服务业', '其他'];
        }

        if (settings.businessScopes.includes(name)) {
            this.showToast('该经营范围已存在', 'warning');
            return;
        }

        settings.businessScopes.push(name);
        await this.dbPut('settings', settings);
        
        this.closeModal('businessScopeModal');
        await this.renderBusinessScopeSettings();
        await this.loadBusinessScopeCheckboxes();
        this.showToast('经营范围已添加', 'success');
    },

    // 删除经营范围
    async deleteBusinessScope(scope) {
        if (!confirm(`确定要删除"${scope}"吗？`)) return;

        const settings = await this.dbGet('settings', 'main');
        if (settings && settings.businessScopes) {
            settings.businessScopes = settings.businessScopes.filter(s => s !== scope);
            await this.dbPut('settings', settings);
            
            await this.renderBusinessScopeSettings();
            await this.loadBusinessScopeCheckboxes();
            this.showToast('经营范围已删除', 'success');
        }
    },

    // 修改经营范围
    async editBusinessScope(oldName, index) {
        const newName = prompt('请输入新的经营范围名称：', oldName);
        if (!newName || newName.trim() === '') return;
        if (newName.trim() === oldName) return;

        const settings = await this.dbGet('settings', 'main');
        if (!settings || !settings.businessScopes) return;

        // 检查是否已存在
        if (settings.businessScopes.includes(newName.trim()) && newName.trim() !== oldName) {
            this.showToast('该经营范围已存在', 'warning');
            return;
        }

        // 更新
        settings.businessScopes[index] = newName.trim();
        await this.dbPut('settings', settings);
        
        await this.renderBusinessScopeSettings();
        await this.loadBusinessScopeCheckboxes();
        this.showToast('经营范围已修改', 'success');
    },

    // 加载客户表单中的经营范围选项
    async loadBusinessScopeCheckboxes() {
        const settings = await this.dbGet('settings', 'main');
        const scopes = settings?.businessScopes || ['建材', '电子产品', '服装', '食品', '服务业', '其他'];

        const html = scopes.map(scope => `
            <label><input type="checkbox" name="businessScope" value="${scope}"> ${scope}</label>
        `).join('');

        document.getElementById('businessScopeCheckboxes').innerHTML = html;
    },

    // ==================== 回访话术 ====================
    async loadScripts() {
        await this.renderScriptTable();
    },

    async renderScriptTable() {
        const scripts = await this.dbGetAll('scripts');
        
        // 阶段过滤
        const stageFilter = document.getElementById('scriptStageFilter').value;
        let filteredScripts = scripts;
        if (stageFilter) {
            filteredScripts = scripts.filter(s => s.stage === stageFilter);
        }

        const tbody = document.getElementById('scriptTableBody');
        
        if (filteredScripts.length === 0) {
            tbody.innerHTML = '<tr><td colspan="5" class="empty-state">暂无话术数据</td></tr>';
            return;
        }

        // 按阶段分组
        const stages = ['初次接触', '需求了解', '产品介绍', '异议处理', '促成成交'];
        const grouped = {};
        stages.forEach(stage => grouped[stage] = []);
        filteredScripts.forEach(script => {
            if (!grouped[script.stage]) grouped[script.stage] = [];
            grouped[script.stage].push(script);
        });

        let html = '';
        for (const stage of stages) {
            const stageScripts = grouped[stage];
            if (stageScripts && stageScripts.length > 0) {
                const stageColors = {
                    '初次接触': '#10B981',
                    '需求了解': '#3B82F6',
                    '产品介绍': '#8B5CF6',
                    '异议处理': '#F59E0B',
                    '促成成交': '#EF4444'
                };
                html += `
                    <tr style="background:#f8f9fa;">
                        <td colspan="5" style="font-weight:600;padding:12px;">
                            <span style="display:inline-block;padding:4px12px;background:${stageColors[stage] || '#667eea'};color:white;border-radius:4px;margin-right:10px;">${stage}</span>
                            <span style="color:#666;">共 ${stageScripts.length} 条话术</span>
                        </td>
                    </tr>
                `;
                html += stageScripts.map(script => `
                    <tr>
                        <td style="text-align:center;"><i class="fas fa-quote-left" style="color:#ccc;"></i></td>
                        <td style="font-weight:500;">${script.title}</td>
                        <td style="max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="${script.content}">${script.content}</td>
                        <td>${script.scenario || '-'}</td>
                        <td class="actions">
                            <button class="btn-action" onclick="app.openScriptModal('${script.id}')" title="编辑">
                                <i class="fas fa-edit"></i>
                            </button>
                            <button class="btn-action delete" onclick="app.deleteScript('${script.id}')" title="删除">
                                <i class="fas fa-trash"></i>
                            </button>
                        </td>
                    </tr>
                `).join('');
            }
        }
        
        tbody.innerHTML = html;
    },

    filterScripts() {
        this.renderScriptTable();
    },

    async openScriptModal(scriptId = null) {
        document.getElementById('scriptForm').reset();
        document.getElementById('scriptId').value = '';
        
        if (scriptId) {
            const scripts = await this.dbGetAll('scripts');
            const script = scripts.find(s => s.id === scriptId);
            if (script) {
                document.getElementById('scriptModalTitle').textContent = '编辑话术';
                document.getElementById('scriptId').value = script.id;
                document.getElementById('scriptStage').value = script.stage;
                document.getElementById('scriptTitle').value = script.title;
                document.getElementById('scriptContent').value = script.content;
                document.getElementById('scriptScenario').value = script.scenario || '';
            }
        } else {
            document.getElementById('scriptModalTitle').textContent = '添加话术';
        }

        this.openModal('scriptModal');
    },

    async saveScript() {
        const id = document.getElementById('scriptId').value;
        const stage = document.getElementById('scriptStage').value;
        const title = document.getElementById('scriptTitle').value.trim();
        const content = document.getElementById('scriptContent').value.trim();
        const scenario = document.getElementById('scriptScenario').value.trim();

        if (!title || !content) {
            this.showToast('请填写标题和内容', 'error');
            return;
        }

        const scripts = await this.dbGetAll('scripts');

        if (id) {
            const index = scripts.findIndex(s => s.id === id);
            if (index !== -1) {
                scripts[index] = { ...scripts[index], stage, title, content, scenario };
                await this.dbPut('scripts', scripts[index]);
            }
        } else {
            const newScript = {
                id: this.generateId(),
                stage,
                title,
                content,
                scenario,
                createdAt: new Date().toISOString()
            };
            await this.dbPut('scripts', newScript);
        }

        this.closeModal('scriptModal');
        this.showToast('话术已保存', 'success');
        await this.renderScriptTable();
    },

    async deleteScript(id) {
        this.showConfirm('删除话术', '确定要删除该话术吗？', async () => {
            await this.dbDelete('scripts', id);
            await this.renderScriptTable();
            this.showToast('话术已删除', 'success');
        }, 'danger');
    },

    // ==================== 产品展示 ====================
    async loadProducts() {
        await this.renderProductGrid();
        await this.renderIndustrySchemeList();
    },

    // 渲染行业方案列表（简化版：名称+缩略图）
    async renderIndustrySchemeList() {
        const schemes = await this.dbGetAll('industry_schemes');
        const gridEl = document.getElementById('productGrid');
        
        // 先移除已有的行业方案区块
        const existingSchemeSection = gridEl.querySelector('.industry-scheme-section');
        if (existingSchemeSection) {
            existingSchemeSection.remove();
        }
        
        if (schemes.length === 0) return;
        
        let html = '<div class="industry-scheme-section" style="grid-column:1/-1;margin-top:20px;padding-top:20px;border-top:1px dashed #ddd;"><h3 style="margin-bottom:15px;"><i class="fas fa-file-alt"></i> 行业方案</h3>';
        html += '<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:20px;">';
        
        html += schemes.map(scheme => `
            <div style="background:white;border-radius:12px;overflow:hidden;box-shadow:0 2px12px rgba(0,0,0,0.1);cursor:pointer;transition:transform0.2s;" onclick="app.openIndustrySchemeModal('${scheme.id}')">
                <div style="height:140px;background:#f0f2f5;display:flex;align-items:center;justify-content:center;overflow:hidden;">
                    ${scheme.image ? 
                        `<img src="${scheme.image}" alt="${scheme.name}" style="width:100%;height:100%;object-fit:cover;">` :
                        `<i class="fas fa-image" style="font-size:48px;color:#ccc;"></i>`
                    }
                </div>
                <div style="padding:12px;">
                    <div style="font-weight:600;color:#333;font-size:14px;margin-bottom:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">${scheme.name}</div>
                    <div style="color:#999;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">${scheme.remark || '暂无备注'}</div>
                </div>
            </div>
        `).join('');
        
        html += '</div></div>';
        gridEl.innerHTML += html;
    },

    // 查看行业方案详情
    async viewIndustryScheme(schemeId) {
        const schemes = await this.dbGetAll('industry_schemes');
        const scheme = schemes.find(s => s.id === schemeId);
        if (!scheme) return;
        
        document.getElementById('schemeViewTitle').textContent = scheme.title;
        
        // 将换行符转换为HTML
        const contentHtml = (scheme.content || '').replace(/\n/g, '<br>');
        
        document.getElementById('schemeViewContent').innerHTML = `
            <div style="padding:10px;">
                <div style="margin-bottom:15px;">
                    <span style="background:#667eea20;color:#667eea;padding:4px12px;border-radius:6px;font-size:13px;">${scheme.industryType} - ${scheme.schemeNumber}</span>
                </div>
                <div style="background:#f8f9fa;padding:16px;border-radius:8px;white-space:pre-wrap;line-height:1.8;">${contentHtml}</div>
            </div>
        `;
        
        document.getElementById('industrySchemeViewModal').classList.add('active');
    },

    // 打开行业方案模态框（简化版）
    async openIndustrySchemeModal(schemeId = null) {
        document.getElementById('industrySchemeForm').reset();
        document.getElementById('industrySchemeId').value = '';
        
        // 隐藏图片预览
        document.getElementById('schemeImagePreview').style.display = 'none';
        
        // 显示/隐藏删除按钮
        const deleteBtn = document.getElementById('deleteSchemeBtn');
        if (schemeId) {
            const schemes = await this.dbGetAll('industry_schemes');
            const scheme = schemes.find(s => s.id === schemeId);
            if (scheme) {
                document.getElementById('industrySchemeModalTitle').textContent = '编辑行业方案';
                document.getElementById('industrySchemeId').value = scheme.id;
                document.getElementById('schemeName').value = scheme.name || '';
                document.getElementById('schemeImage').value = scheme.image || '';
                document.getElementById('schemeRemark').value = scheme.remark || '';
                deleteBtn.style.display = 'block';
            }
        } else {
            document.getElementById('industrySchemeModalTitle').textContent = '添加行业方案';
            deleteBtn.style.display = 'none';
        }
        
        document.getElementById('industrySchemeModal').classList.add('active');
    },
    
    // 预览行业方案图片
    async previewSchemeImage() {
        const imageUrl = document.getElementById('schemeImage').value.trim();
        const previewContainer = document.getElementById('schemeImagePreview');
        const previewImg = document.getElementById('schemePreviewImg');
        
        if (!imageUrl) {
            this.showToast('请输入图片URL', 'warning');
            return;
        }
        
        previewImg.src = imageUrl;
        previewContainer.style.display = 'block';
        
        previewImg.onerror = () => {
            previewContainer.style.display = 'none';
            this.showToast('图片加载失败，请检查URL是否正确', 'error');
        };
    },
    
    // 删除行业方案
    async deleteIndustryScheme() {
        const id = document.getElementById('industrySchemeId').value;
        if (!id) return;
        
        this.showConfirm('确认删除', '确定要删除这个行业方案吗？', async () => {
            await this.dbDelete('industry_schemes', id);
            this.closeModal('industrySchemeModal');
            await this.renderIndustrySchemeList();
            this.showToast('行业方案已删除', 'success');
        }, 'danger');
    },

    // 保存行业方案（简化版）
    async saveIndustryScheme() {
        const id = document.getElementById('industrySchemeId').value;
        const name = document.getElementById('schemeName').value.trim();
        const image = document.getElementById('schemeImage').value.trim();
        const remark = document.getElementById('schemeRemark').value.trim();
        
        if (!name) {
            this.showToast('请填写方案名称', 'warning');
            return;
        }
        
        const existingScheme = id ? await this.dbGet('industry_schemes', id) : null;
        
        const scheme = {
            id: id || this.generateId(),
            name,
            image,
            remark,
            createdAt: existingScheme?.createdAt || new Date().toISOString(),
            updatedAt: new Date().toISOString()
        };
        
        await this.dbPut('industry_schemes', scheme);
        
        this.closeModal('industrySchemeModal');
        await this.renderIndustrySchemeList();
        this.showToast('行业方案已保存', 'success');
    },

    async renderProductGrid() {
        let products = await this.dbGetAll('products');
        
        // 搜索
        const search = document.getElementById('productSearch').value.trim().toLowerCase();
        if (search) {
            products = products.filter(p => p.name.toLowerCase().includes(search));
        }

        // 分类过滤
        const categoryFilter = document.getElementById('productCategoryFilter').value;
        if (categoryFilter) {
            products = products.filter(p => p.category === categoryFilter);
        }

        const gridEl = document.getElementById('productGrid');
        
        // 保留行业方案区块（如果有的话）
        const existingSchemeSection = gridEl.querySelector('.industry-scheme-section');
        
        if (products.length === 0) {
            gridEl.innerHTML = '<div class="empty-state" style="grid-column: 1/-1;"><p>暂无产品数据</p></div>';
            // 重新添加行业方案区块
            if (existingSchemeSection) {
                gridEl.appendChild(existingSchemeSection);
            }
            return;
        }

        gridEl.innerHTML = products.map(product => `
            <div class="product-card">
                <div class="product-card-image">
                    ${product.images && product.images.length > 0 
                        ? `<img src="${product.images[0]}" alt="${product.name}">`
                        : `<i class="fas fa-box"></i>`
                    }
                </div>
                <div class="product-card-body">
                    <div class="product-card-category">${product.category}</div>
                    <div class="product-card-name">${product.name}</div>
                    <div class="product-card-price">¥${product.price || 0}</div>
                    <div class="product-card-meta">
                        <span>${product.spec || '-'}</span>
                        <span class="product-card-stock ${product.stock === '有货' ? 'in-stock' : 'out-of-stock'}">${product.stock}</span>
                    </div>
                    <div class="product-card-actions">
                        <button class="btn btn-sm btn-primary" onclick="app.openProductModal('${product.id}')">
                            <i class="fas fa-edit"></i> 编辑
                        </button>
                        <button class="btn btn-sm btn-danger" onclick="app.deleteProduct('${product.id}')">
                            <i class="fas fa-trash"></i> 删除
                        </button>
                    </div>
                </div>
            </div>
        `).join('');

        // 重新添加行业方案区块
        if (existingSchemeSection) {
            gridEl.appendChild(existingSchemeSection);
        }
    },

    searchProducts() {
        this.renderProductGrid();
    },

    filterProducts() {
        this.renderProductGrid();
    },

    toggleView(view) {
        const grid = document.getElementById('productGrid');
        const buttons = document.querySelectorAll('.view-toggle .btn-icon');
        
        buttons.forEach(btn => {
            btn.classList.toggle('active', btn.dataset.view === view);
        });
        
        if (view === 'list') {
            grid.classList.add('list-view');
        } else {
            grid.classList.remove('list-view');
        }
    },

    async openProductModal(productId = null) {
        this.productPhotos = [];
        document.getElementById('productForm').reset();
        document.getElementById('productId').value = '';
        document.getElementById('productPhotoPreviewList').innerHTML = '';
        
        if (productId) {
            const products = await this.dbGetAll('products');
            const product = products.find(p => p.id === productId);
            if (product) {
                document.getElementById('productModalTitle').textContent = '编辑产品';
                document.getElementById('productId').value = product.id;
                document.getElementById('productName').value = product.name;
                document.getElementById('productCategory').value = product.category;
                document.getElementById('productPrice').value = product.price;
                document.getElementById('productSpec').value = product.spec || '';
                document.getElementById('productStock').value = product.stock;
                document.getElementById('productDescription').value = product.description || '';
                
                if (product.images && product.images.length > 0) {
                    this.productPhotos = [...product.images];
                    this.renderProductPhotos();
                }
            }
        } else {
            document.getElementById('productModalTitle').textContent = '添加产品';
        }

        this.openModal('productModal');
    },

    handleProductPhotoUpload(input) {
        if (input.files && input.files.length > 0) {
            const files = Array.from(input.files);
            const remaining = 5 - this.productPhotos.length;
            
            if (remaining <= 0) {
                this.showToast('最多只能上传5张图片', 'warning');
                return;
            }

            const filesToProcess = files.slice(0, remaining);
            
            filesToProcess.forEach(file => {
                if (file.size > 5 * 1024 * 1024) {
                    this.showToast('单张图片不能超过5MB', 'warning');
                    return;
                }

                const reader = new FileReader();
                reader.onload = (e) => {
                    this.productPhotos.push(e.target.result);
                    this.renderProductPhotos();
                };
                reader.readAsDataURL(file);
            });
        }
        input.value = '';
    },

    renderProductPhotos() {
        const container = document.getElementById('productPhotoPreviewList');
        container.innerHTML = this.productPhotos.map((photo, index) => `
            <div class="photo-preview">
                <img src="${photo}" alt="产品图片">
                <div class="photo-delete" onclick="app.deleteProductPhoto(${index})">
                    <i class="fas fa-times"></i>
                </div>
            </div>
        `).join('');
    },

    deleteProductPhoto(index) {
        this.productPhotos.splice(index, 1);
        this.renderProductPhotos();
    },

    async saveProduct() {
        const id = document.getElementById('productId').value;
        const name = document.getElementById('productName').value.trim();
        
        if (!name) {
            this.showToast('请填写产品名称', 'error');
            return;
        }

        const productData = {
            name,
            category: document.getElementById('productCategory').value,
            price: parseFloat(document.getElementById('productPrice').value) || 0,
            spec: document.getElementById('productSpec').value.trim(),
            stock: document.getElementById('productStock').value,
            description: document.getElementById('productDescription').value.trim(),
            images: this.productPhotos
        };

        const products = await this.dbGetAll('products');

        if (id) {
            const index = products.findIndex(p => p.id === id);
            if (index !== -1) {
                products[index] = { ...products[index], ...productData };
                await this.dbPut('products', products[index]);
            }
        } else {
            const newProduct = {
                id: this.generateId(),
                ...productData,
                createdAt: new Date().toISOString()
            };
            await this.dbPut('products', newProduct);
        }

        this.closeModal('productModal');
        this.showToast('产品已保存', 'success');
        await this.renderProductGrid();
    },

    async deleteProduct(id) {
        this.showConfirm('删除产品', '确定要删除该产品吗？', async () => {
            await this.dbDelete('products', id);
            await this.renderProductGrid();
            this.showToast('产品已删除', 'success');
        }, 'danger');
    },

    // ==================== 用户权限 ====================
    async loadUsers() {
        await this.renderUserTable();
    },

    async renderUserTable() {
        const users = await this.getAllUsers();
        const customers = await this.dbGetAll('customers');
        const groups = await this.getAllPermissionGroups();
        
        const tbody = document.getElementById('userTableBody');
        
        if (users.length === 0) {
            tbody.innerHTML = '<tr><td colspan="8" class="empty-state">暂无用户数据</td></tr>';
            return;
        }

        tbody.innerHTML = users.map(user => {
            // 计算该用户名下的客户数量
            const customerCount = customers.filter(c => c.ownerUsers && c.ownerUsers.includes(user.id)).length;
            
            // 获取权限组名称
            let groupName = '-';
            if (user.role === 'admin') {
                groupName = '管理员组(全部权限)';
            } else if (user.permissionGroup) {
                const group = groups.find(g => g.code === user.permissionGroup);
                groupName = group ? group.name : '-';
            }
            
            return `
            <tr>
                <td>${user.username}</td>
                <td>${user.realName}</td>
                <td><span class="level-tag" style="background: #EEF2FF; color: #4F46E5;">${this.getRoleName(user.role)}</span></td>
                <td><span style="font-weight: 500;">${groupName}</span></td>
                <td><span style="font-weight: 600; color: var(--primary);">${customerCount}</span> 人</td>
                <td><span class="status-tag ${user.status}">${user.status === 'active' ? '启用' : '禁用'}</span></td>
                <td>${user.createdAt.split('T')[0]}</td>
                <td class="actions">
                    <button class="btn-action" onclick="app.openUserModal('${user.id}')" title="编辑">
                        <i class="fas fa-edit"></i>
                    </button>
                    ${user.role !== 'admin' ? `
                    <button class="btn-action delete" onclick="app.deleteUser('${user.id}')" title="删除">
                        <i class="fas fa-trash"></i>
                    </button>
                    ` : ''}
                </td>
            </tr>
            `;
        }).join('');
    },

    // 渲染权限组选择下拉框
    async renderPermissionGroupSelect() {
        const groups = await this.getAllPermissionGroups();
        const select = document.getElementById('userPermissionGroup');
        const role = document.getElementById('userRole').value;
        
        // 管理员角色不显示权限组选择
        if (role === 'admin') {
            document.getElementById('permissionGroupField').style.display = 'none';
            return;
        }
        
        document.getElementById('permissionGroupField').style.display = 'block';
        
        select.innerHTML = groups
            .filter(g => !g.isSystem || g.code === 'admin_group')
            .map(g => `<option value="${g.code}">${g.name}</option>`)
            .join('');
    },

    // 用户角色变更时触发
    onUserRoleChange() {
        this.renderPermissionGroupSelect();
    },

    // 省份改变时更新城市选择
    onProvinceChange() {
        const province = document.getElementById('customerProvince').value;
        const citySelect = document.getElementById('customerCity');
        
        if (!citySelect) return;
        
        citySelect.innerHTML = '<option value="">请选择城市</option>';
        
        if (province && this.provinceCityData[province]) {
            this.provinceCityData[province].forEach(city => {
                const option = document.createElement('option');
                option.value = city;
                option.textContent = city;
                citySelect.appendChild(option);
            });
        }
    },

    async openUserModal(userId = null) {
        document.getElementById('userForm').reset();
        document.getElementById('userId').value = '';
        
        // 初始化权限组下拉框
        await this.renderPermissionGroupSelect();
        
        if (userId) {
            const users = await this.getAllUsers();
            const user = users.find(u => u.id === userId);
            if (user) {
                document.getElementById('userModalTitle').textContent = '编辑用户';
                document.getElementById('userId').value = user.id;
                document.getElementById('userUsername').value = user.username;
                document.getElementById('userRealName').value = user.realName;
                document.getElementById('userRole').value = user.role;
                document.getElementById('userStatus').value = user.status;
                document.getElementById('passwordGroup').querySelector('label').innerHTML = '密码 <span class="required">*</span> (留空不修改)';
                document.getElementById('userPassword').required = false;
                
                // 渲染权限组
                await this.renderPermissionGroupSelect();
                
                // 设置权限组
                if (user.permissionGroup) {
                    document.getElementById('userPermissionGroup').value = user.permissionGroup;
                }
                
                // 管理员角色用户名不可编辑
                if (user.role === 'admin') {
                    document.getElementById('userUsername').readOnly = true;
                } else {
                    document.getElementById('userUsername').readOnly = false;
                }
            }
        } else {
            document.getElementById('userModalTitle').textContent = '添加用户';
            document.getElementById('passwordGroup').querySelector('label').innerHTML = '密码 <span class="required">*</span>';
            document.getElementById('userPassword').required = true;
            document.getElementById('userUsername').readOnly = false;
        }

        this.openModal('userModal');
    },

    async saveUser() {
        const id = document.getElementById('userId').value;
        const username = document.getElementById('userUsername').value.trim();
        const realName = document.getElementById('userRealName').value.trim();
        const password = document.getElementById('userPassword').value;
        const role = document.getElementById('userRole').value;
        const status = document.getElementById('userStatus').value;
        const permissionGroup = document.getElementById('userPermissionGroup').value;

        if (!username || !realName) {
            this.showToast('请填写用户名和姓名', 'error');
            return;
        }

        if (!id && !password) {
            this.showToast('请填写密码', 'error');
            return;
        }

        const users = await this.getAllUsers();

        // 检查用户名重复
        const existingUser = users.find(u => u.username === username && u.id !== id);
        if (existingUser) {
            this.showToast('用户名已存在', 'error');
            return;
        }

        if (id) {
            const index = users.findIndex(u => u.id === id);
            if (index !== -1) {
                users[index].realName = realName;
                // 只有非管理员角色可以修改角色
                if (users[index].role !== 'admin') {
                    users[index].role = role;
                    users[index].permissionGroup = permissionGroup;
                }
                users[index].status = status;
                if (password) {
                    users[index].password = await this.hashPassword(password);
                }
                await this.dbPut('users', users[index]);
            }
        } else {
            const newUser = {
                id: this.generateId(),
                username,
                password: await this.hashPassword(password),
                realName,
                role,
                permissionGroup,
                status,
                createdAt: new Date().toISOString()
            };
            await this.dbPut('users', newUser);
        }

        this.closeModal('userModal');
        await this.renderUserTable();
        this.showToast('用户保存成功', 'success');
    },

    async deleteUser(id) {
        const users = await this.getAllUsers();
        const user = users.find(u => u.id === id);
        
        // 管理员不能被删除
        if (user && user.role === 'admin') {
            this.showToast('管理员账号不能被删除', 'error');
            return;
        }
        
        this.showConfirm('删除用户', '确定要删除该用户吗？', async () => {
            await this.dbDelete('users', id);
            await this.renderUserTable();
            this.showToast('用户已删除', 'success');
        }, 'danger');
    },

    // ==================== 权限组管理 ====================
    async loadPermissionGroups() {
        await this.renderPermissionGroupTable();
    },

    async renderPermissionGroupTable() {
        const groups = await this.getAllPermissionGroups();
        const tbody = document.getElementById('permissionGroupTableBody');
        
        if (groups.length === 0) {
            tbody.innerHTML = '<tr><td colspan="6" class="empty-state">暂无权限组数据</td></tr>';
            return;
        }

        tbody.innerHTML = groups.map(group => `
            <tr>
                <td><strong>${group.name}</strong></td>
                <td><code>${group.code}</code></td>
                <td>${group.description || '-'}</td>
                <td><span style="font-weight: 600; color: var(--primary);">${group.permissions ? group.permissions.length : 0}</span> 项</td>
                <td>${group.isSystem ? '<span class="status-tag" style="background: #FEE2E2; color: #DC2626;">系统预设</span>' : '<span class="status-tag" style="background: #E0F2FE; color: #0284C7;">自定义</span>'}</td>
                <td class="actions">
                    <button class="btn-action" onclick="app.openPermissionGroupModal('${group.id}')" title="编辑">
                        <i class="fas fa-edit"></i>
                    </button>
                    ${!group.isSystem ? `
                    <button class="btn-action delete" onclick="app.deletePermissionGroup('${group.id}')" title="删除">
                        <i class="fas fa-trash"></i>
                    </button>
                    ` : ''}
                </td>
            </tr>
        `).join('');
    },

    async openPermissionGroupModal(groupId = null) {
        document.getElementById('permissionGroupForm').reset();
        document.getElementById('permissionGroupId').value = '';
        
        // 渲染权限复选框
        this.renderPermissionCheckboxes();
        
        if (groupId) {
            const groups = await this.getAllPermissionGroups();
            const group = groups.find(g => g.id === groupId);
            if (group) {
                document.getElementById('permissionGroupModalTitle').textContent = '编辑权限组';
                document.getElementById('permissionGroupId').value = group.id;
                document.getElementById('permissionGroupName').value = group.name;
                document.getElementById('permissionGroupCode').value = group.code;
                document.getElementById('permissionGroupDesc').value = group.description || '';
                
                // 选中已有权限
                if (group.permissions && group.permissions.length > 0) {
                    document.querySelectorAll('.permission-checkbox').forEach(cb => {
                        cb.checked = group.permissions.includes(cb.value);
                    });
                }
                
                // 系统预设不可修改编码
                if (group.isSystem) {
                    document.getElementById('permissionGroupCode').readOnly = true;
                } else {
                    document.getElementById('permissionGroupCode').readOnly = false;
                }
            }
        } else {
            document.getElementById('permissionGroupModalTitle').textContent = '新增权限组';
            document.getElementById('permissionGroupCode').readOnly = false;
        }

        this.openModal('permissionGroupModal');
    },

    renderPermissionCheckboxes() {
        const container = document.getElementById('permissionCheckboxes');
        let html = '';
        
        // 按分类显示权限
        for (const [category, perms] of Object.entries(this.PERMISSIONS)) {
            const categoryNames = {
                customer: '客户管理',
                script: '回访话术',
                product: '产品展示',
                data: '数据管理',
                user: '用户管理'
            };
            
            html += `<div class="permission-category"><h4>${categoryNames[category] || category}</div>`;
            html += '<div class="permission-items">';
            
            for (const [key, name] of Object.entries(perms)) {
                const permKey = `${category}.${key}`;
                html += `
                    <label class="permission-item">
                        <input type="checkbox" class="permission-checkbox" value="${permKey}">
                        <span>${name}</span>
                    </label>
                `;
            }
            
            html += '</div>';
        }
        
        container.innerHTML = html;
        
        // 添加样式（如果需要）
        if (!document.getElementById('permissionStyles')) {
            const style = document.createElement('style');
            style.id = 'permissionStyles';
            style.textContent = `
                .permission-category {
                    margin-bottom: 12px;
                    padding-bottom: 8px;
                    border-bottom: 1px solid var(--border);
                }
                .permission-category h4 {
                    margin: 0 0 8px 0;
                    font-size: 14px;
                    color: var(--text-primary);
                }
                .permission-items {
                    display: flex;
                    flex-wrap: wrap;
                    gap: 8px;
                }
                .permission-item {
                    display: flex;
                    align-items: center;
                    gap: 6px;
                    padding: 6px 12px;
                    background: var(--bg);
                    border-radius: var(--radius);
                    font-size: 13px;
                    cursor: pointer;
                }
                .permission-item:hover {
                    background: var(--border);
                }
            `;
            document.head.appendChild(style);
        }
    },

    async savePermissionGroup() {
        const id = document.getElementById('permissionGroupId').value;
        const name = document.getElementById('permissionGroupName').value.trim();
        const code = document.getElementById('permissionGroupCode').value.trim();
        const description = document.getElementById('permissionGroupDesc').value.trim();
        
        // 收集权限
        const permissions = [];
        document.querySelectorAll('.permission-checkbox:checked').forEach(cb => {
            permissions.push(cb.value);
        });

        if (!name || !code) {
            this.showToast('请填写权限组名称和编码', 'error');
            return;
        }

        const groups = await this.getAllPermissionGroups();

        // 检查编码重复
        const existingCode = groups.find(g => g.code === code && g.id !== id);
        if (existingCode) {
            this.showToast('权限组编码已存在', 'error');
            return;
        }

        if (id) {
            const index = groups.findIndex(g => g.id === id);
            if (index !== -1) {
                groups[index].name = name;
                if (!groups[index].isSystem) {
                    groups[index].code = code;
                }
                groups[index].description = description;
                groups[index].permissions = permissions;
                await this.dbPut('permission_groups', groups[index]);
            }
        } else {
            const newGroup = {
                id: this.generateId(),
                name,
                code,
                description,
                permissions,
                isSystem: false,
                createdAt: new Date().toISOString()
            };
            await this.dbPut('permission_groups', newGroup);
        }

        this.closeModal('permissionGroupModal');
        this.showToast('权限组已保存', 'success');
        await this.renderPermissionGroupTable();
    },

    async deletePermissionGroup(id) {
        const groups = await this.getAllPermissionGroups();
        const group = groups.find(g => g.id === id);
        
        if (group && group.isSystem) {
            this.showToast('系统预设权限组不能删除', 'error');
            return;
        }
        
        // 检查是否有用户使用此权限组
        const users = await this.getAllUsers();
        const usingUsers = users.filter(u => u.permissionGroup === group.code);
        if (usingUsers.length > 0) {
            this.showToast(`该权限组正在被 ${usingUsers.length} 个用户使用，无法删除`, 'error');
            return;
        }

        this.showConfirm('删除权限组', '确定要删除该权限组吗？', async () => {
            await this.dbDelete('permission_groups', id);
            await this.renderPermissionGroupTable();
            this.showToast('权限组已删除', 'success');
        }, 'danger');
    },

    // ==================== 系统设置 ====================
    async loadSettings() {
        document.getElementById('profileRealName').value = this.currentUser.realName;
        this.updateLastBackupDisplay();
        
        // 检查通知权限状态
        if ('Notification' in window && Notification.permission === 'granted') {
            const btn = document.getElementById('enableNotifyBtn');
            const bar = document.getElementById('notifyStatusBar');
            if (btn) btn.style.display = 'none';
            if (bar) bar.style.display = 'block';
        }
    },

    async saveProfile() {
        const realName = document.getElementById('profileRealName').value.trim();
        const oldPassword = document.getElementById('profileOldPassword') ? document.getElementById('profileOldPassword').value : '';
        const newPassword = document.getElementById('profileNewPassword').value;
        const confirmPassword = document.getElementById('profileConfirmPassword') ? document.getElementById('profileConfirmPassword').value : '';

        if (!realName) {
            this.showToast('请填写姓名', 'error');
            return;
        }

        const users = await this.getAllUsers();
        const index = users.findIndex(u => u.id === this.currentUser.id);

        if (index !== -1) {
            users[index].realName = realName;
            
            if (newPassword) {
                // 验证旧密码
                if (oldPassword) {
                    const validOld = await this.verifyPassword(oldPassword, users[index].password);
                    if (!validOld) {
                        this.showToast('原密码错误', 'error');
                        return;
                    }
                }
                
                // 确认新密码一致
                if (confirmPassword && newPassword !== confirmPassword) {
                    this.showToast('两次输入的密码不一致', 'error');
                    return;
                }
                
                // 密码强度检测
                if (newPassword.length < 6) {
                    this.showToast('密码长度不能少于6位', 'error');
                    return;
                }
                
                users[index].password = await this.hashPassword(newPassword);
            }
            
            await this.dbPut('users', users[index]);
            
            // 更新当前用户
            this.currentUser = users[index];
            localStorage.setItem('crv_current_user_id', this.currentUser.id);
            
            document.getElementById('currentUserName').textContent = this.currentUser.realName;
            document.getElementById('profileNewPassword').value = '';
            if (document.getElementById('profileOldPassword')) document.getElementById('profileOldPassword').value = '';
            if (document.getElementById('profileConfirmPassword')) document.getElementById('profileConfirmPassword').value = '';
            
            this.showToast('个人信息已更新', 'success');
        }
    },

    async exportData() {
        // 兼容旧调用，转发到新的备份导出
        await this.exportDataBackup();
    },

    async importData(input) {
        // 权限检查
        if (!await this.hasPermission('data.import')) {
            this.showToast('您没有导入数据的权限', 'error');
            return;
        }
        if (input.files && input.files[0]) {
            const file = input.files[0];
            const reader = new FileReader();
            
            reader.onload = async (e) => {
                try {
                    const data = JSON.parse(e.target.result);
                    
                    this.showConfirm('导入数据', '导入数据将覆盖现有数据，此操作不可撤销，确定要继续吗？', async () => {
                        // v2.0格式（对象直接存储）
                        if (data.version === '2.0') {
                            if (data.users) for (const u of data.users) await this.dbPut('users', u);
                            if (data.customers) for (const c of data.customers) await this.dbPut('customers', c);
                            if (data.scripts) for (const s of data.scripts) await this.dbPut('scripts', s);
                            if (data.products) for (const p of data.products) await this.dbPut('products', p);
                            if (data.visitRecords) for (const r of data.visitRecords) await this.dbPut('visit_records', r);
                            if (data.settings && data.settings.id) await this.dbPut('settings', data.settings);
                            if (data.permission_groups) for (const g of data.permission_groups) await this.dbPut('permission_groups', g);
                        } else {
                            // v1.0格式（JSON字符串）
                            if (data.users) { const users = JSON.parse(data.users); for (const u of users) await this.dbPut('users', u); }
                            if (data.customers) { const customers = JSON.parse(data.customers); for (const c of customers) await this.dbPut('customers', c); }
                            if (data.scripts) { const scripts = JSON.parse(data.scripts); for (const s of scripts) await this.dbPut('scripts', s); }
                            if (data.products) { const products = JSON.parse(data.products); for (const p of products) await this.dbPut('products', p); }
                            if (data.visitRecords) { const records = JSON.parse(data.visitRecords); for (const r of records) await this.dbPut('visit_records', r); }
                            if (data.settings) { const settings = JSON.parse(data.settings); await this.dbPut('settings', settings); }
                        }
                        
                        this.showToast('数据导入成功，正在重新加载...', 'success');
                        setTimeout(() => { this.handleLogout(); }, 1500);
                    }, 'warning');
                } catch (err) {
                    this.showToast('文件格式错误，请检查文件', 'error');
                }
            };
            
            reader.readAsText(file);
        }
        input.value = '';
    },

    // 导入客户数据(从Excel或CSV文件)
    async importCustomers(input) {
        // 权限检查
        if (!await this.hasPermission('data.import')) {
            this.showToast('您没有导入数据的权限', 'error');
            return;
        }

        if (!input.files || !input.files[0]) {
            return;
        }

        const file = input.files[0];
        const fileName = file.name.toLowerCase();

        try {
            let customersData = [];

            // 根据文件类型解析数据
            if (fileName.endsWith('.xlsx') || fileName.endsWith('.xls')) {
                // Excel文件解析
                const reader = new FileReader();
                reader.onload = async (e) => {
                    try {
                        const data = new Uint8Array(e.target.result);
                        const workbook = XLSX.read(data, { type: 'array' });
                        const firstSheetName = workbook.SheetNames[0];
                        const worksheet = workbook.Sheets[firstSheetName];
                        const jsonData = XLSX.utils.sheet_to_json(worksheet);
                        await this.processImportedCustomers(jsonData);
                    } catch (err) {
                        console.error('Excel解析失败:', err);
                        this.showToast('Excel文件解析失败: ' + err.message, 'error');
                    }
                };
                reader.readAsArrayBuffer(file);
            } else if (fileName.endsWith('.csv')) {
                // CSV文件解析
                const reader = new FileReader();
                reader.onload = async (e) => {
                    try {
                        const data = new Uint8Array(e.target.result);
                        const workbook = XLSX.read(data, { type: 'array', raw: false });
                        const firstSheetName = workbook.SheetNames[0];
                        const worksheet = workbook.Sheets[firstSheetName];
                        const jsonData = XLSX.utils.sheet_to_json(worksheet);
                        await this.processImportedCustomers(jsonData);
                    } catch (err) {
                        console.error('CSV解析失败:', err);
                        this.showToast('CSV文件解析失败: ' + err.message, 'error');
                    }
                };
                reader.readAsArrayBuffer(file);
            } else {
                this.showToast('不支持的文件格式，请使用Excel(.xlsx/.xls)或CSV文件', 'error');
            }
        } catch (e) {
            console.error('导入失败:', e);
            this.showToast('导入失败: ' + e.message, 'error');
        }

        input.value = '';
    },

    // 处理导入的客户数据
    async processImportedCustomers(jsonData) {
        if (!jsonData || jsonData.length === 0) {
            this.showToast('文件中没有找到客户数据', 'warning');
            return;
        }

        const users = await this.getAllUsers();
        const validUsers = users.filter(u => u.status === 'active');
        const defaultUser = validUsers[0];

        if (!defaultUser) {
            this.showToast('系统中没有可用的归属用户，请先添加用户', 'error');
            return;
        }

        const existingCustomers = await this.getCustomers();
        const existingPhoneSet = new Set(existingCustomers.map(c => c.phone));

        let successCount = 0;
        let duplicateCount = 0;
        let errorCount = 0;
        const errors = [];

        for (let i = 0; i < jsonData.length; i++) {
            try {
                const row = jsonData[i];

                // 跳过空行
                if (!row['姓名'] && !row['电话']) {
                    continue;
                }

                // 必填字段检查
                if (!row['姓名'] || !row['电话']) {
                    errorCount++;
                    errors.push(`第${i + 1}行: 缺少姓名或电话`);
                    continue;
                }

                // 去除空白字符
                const name = String(row['姓名']).trim();
                const phone = String(row['电话']).trim();

                // 检查电话是否重复
                if (existingPhoneSet.has(phone)) {
                    duplicateCount++;
                    continue;
                }

                // 构建客户数据
                const customerData = {
                    id: this.generateId(),
                    name: name,
                    phone: phone,
                    company: row['公司'] ? String(row['公司']).trim() : '',
                    level: this.parseLevel(row['等级']),
                    province: row['省份'] ? String(row['省份']).trim() : '',
                    city: row['城市'] ? String(row['城市']).trim() : '',
                    address: row['详细地址'] ? String(row['详细地址']).trim() : '',
                    returnVisitDays: parseInt(row['回访周期(天)']) || 30,
                    businessScope: row['经营范围'] ? String(row['经营范围']).split(/、|\/|,/).map(s => s.trim()).filter(Boolean) : [],
                    tags: row['客户标签'] ? String(row['客户标签']).split(/、|\/|,/).map(s => s.trim()).filter(Boolean) : [],
                    nextVisitDate: this.parseNextVisitDate(row['下次回访日期']),
                    status: this.parseStatus(row['状态']),
                    remark: row['备注'] ? String(row['备注']).trim() : '',
                    ownerUsers: [defaultUser.id], // 默认归属给第一个可用用户
                    lastVisitDate: null,
                    stage: '初次接触',
                    createdAt: new Date().toISOString()
                };

                await this.dbPut('customers', customerData);
                existingPhoneSet.add(phone);
                successCount++;
            } catch (err) {
                console.error(`导入第${i + 1}行失败:`, err);
                errorCount++;
                errors.push(`第${i + 1}行: ${err.message}`);
            }
        }

        // 显示导入结果
        let message = `导入完成！成功导入 ${successCount} 个客户`;
        if (duplicateCount > 0) message += `，跳过重复 ${duplicateCount} 个`;
        if (errorCount > 0) {
            message += `，失败 ${errorCount} 个`;
            console.error('导入错误详情:', errors);
        }

        // 同步到服务器
        if (successCount > 0) {
            try {
                await API.sync.push(this);
                message += '，已同步到服务器';
            } catch (e) {
                console.warn('导入后同步服务器失败:', e);
                message += '（离线保存，本地已存）';
            }
        }

        this.showToast(message, successCount > 0 ? 'success' : 'warning');

        // 刷新客户列表
        if (document.getElementById('pageCustomers').classList.contains('active')) {
            await this.loadCustomers();
        }
        if (document.getElementById('pageDashboard').classList.contains('active')) {
            await this.loadDashboard();
        }
    },

    // 解析客户等级
    parseLevel(levelStr) {
        if (!levelStr) return 'C';
        const str = String(levelStr).trim().toUpperCase();
        if (['A', 'A级', '重点客户'].includes(str)) return 'A';
        if (['B', 'B级', '重要客户'].includes(str)) return 'B';
        if (['C', 'C级', '普通客户'].includes(str)) return 'C';
        if (['D', 'D级', '潜在客户'].includes(str)) return 'D';
        return 'C';
    },

    // 解析下次回访日期
    parseNextVisitDate(dateStr) {
        if (!dateStr) return this.getDateString(new Date());
        try {
            const date = new Date(dateStr);
            if (!isNaN(date.getTime())) {
                return this.getDateString(date);
            }
        } catch (e) {
            console.error('日期解析失败:', e);
        }
        return this.getDateString(new Date());
    },

    // 解析状态
    parseStatus(statusStr) {
        if (!statusStr) return 'active';
        const str = String(statusStr).trim();
        if (['已停用', '停用', 'inactive', 'disabled'].includes(str)) return 'inactive';
        return 'active';
    },

    async confirmClearAllData() {
        // 权限检查
        if (!await this.hasPermission('data.clear')) {
            this.showToast('您没有清空数据的权限', 'error');
            return;
        }

        this.showConfirm('清空所有数据', '此操作将永久删除所有客户、回访记录等数据，且无法恢复！请确认您已经做好数据备份。', async () => {
            this.showConfirm('二次确认', '再次确认：所有数据将被永久删除，是否继续？', async () => {
                await this.dbClear('users');
                await this.dbClear('customers');
                await this.dbClear('scripts');
                await this.dbClear('products');
                await this.dbClear('visit_records');
                await this.dbClear('settings');
                await this.dbClear('permission_groups');
                
                await this.initData();
                this.showToast('数据已清空', 'success');
                setTimeout(() => { this.handleLogout(); }, 1500);
            }, 'danger');
        }, 'danger');
    },

    async clearAllData() {
        await this.confirmClearAllData();
    },

    // ==================== Toast通知系统 ====================
    showToast(message, type = 'info', duration = 3000) {
        // 创建Toast容器（如果不存在）
        let container = document.getElementById('toastContainer');
        if (!container) {
            container = document.createElement('div');
            container.id = 'toastContainer';
            container.style.cssText = 'position:fixed;top:20px;right:20px;z-index:99999;display:flex;flex-direction:column;gap:10px;';
            document.body.appendChild(container);
        }

        const icons = { success: 'fa-check-circle', error: 'fa-times-circle', warning: 'fa-exclamation-triangle', info: 'fa-info-circle' };
        const colors = { success: '#10B981', error: '#EF4444', warning: '#F59E0B', info: '#3B82F6' };

        const toast = document.createElement('div');
        toast.style.cssText = `
            display:flex;align-items:center;gap:10px;padding:12px 18px;
            background:white;border-radius:10px;box-shadow:0 4px 20px rgba(0,0,0,0.15);
            border-left:4px solid ${colors[type]};min-width:250px;max-width:380px;
            transform:translateX(110%);transition:transform 0.3s ease;
            font-size:14px;color:#1F2937;
        `;
        toast.innerHTML = `
            <i class="fas ${icons[type]}" style="color:${colors[type]};font-size:18px;flex-shrink:0;"></i>
            <span style="flex:1;">${message}</span>
            <button onclick="this.parentElement.remove()" style="background:none;border:none;color:#9CA3AF;cursor:pointer;font-size:16px;padding:0;line-height:1;">&times;</button>
        `;
        container.appendChild(toast);
        
        // 动画进入
        requestAnimationFrame(() => {
            requestAnimationFrame(() => { toast.style.transform = 'translateX(0)'; });
        });

        // 自动消失
        setTimeout(() => {
            toast.style.transform = 'translateX(110%)';
            setTimeout(() => toast.remove(), 300);
        }, duration);
    },

    // ==================== 确认对话框 ====================
    showConfirm(title, message, onConfirm, type = 'warning') {
        const colors = { warning: '#F59E0B', danger: '#EF4444', info: '#3B82F6' };
        const icons = { warning: 'fa-exclamation-triangle', danger: 'fa-trash', info: 'fa-question-circle' };

        // 移除已有对话框
        const existing = document.getElementById('confirmDialog');
        if (existing) existing.remove();

        const overlay = document.createElement('div');
        overlay.id = 'confirmDialog';
        overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:99998;display:flex;align-items:center;justify-content:center;';
        overlay.innerHTML = `
            <div style="background:white;border-radius:16px;padding:32px;max-width:400px;width:90%;text-align:center;box-shadow:0 20px 60px rgba(0,0,0,0.3);">
                <div style="width:60px;height:60px;border-radius:50%;background:${colors[type]}20;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">
                    <i class="fas ${icons[type]}" style="font-size:28px;color:${colors[type]};"></i>
                </div>
                <h3 style="margin:0 0 10px;font-size:18px;color:#1F2937;">${title}</h3>
                <p style="color:#6B7280;font-size:14px;margin:0 0 24px;line-height:1.6;">${message}</p>
                <div style="display:flex;gap:12px;justify-content:center;">
                    <button id="confirmCancel" style="padding:10px 24px;border:1px solid #E5E7EB;background:white;border-radius:8px;cursor:pointer;font-size:14px;color:#6B7280;">取消</button>
                    <button id="confirmOk" style="padding:10px 24px;background:${colors[type]};color:white;border:none;border-radius:8px;cursor:pointer;font-size:14px;font-weight:600;">确认</button>
                </div>
            </div>
        `;
        document.body.appendChild(overlay);

        document.getElementById('confirmOk').onclick = () => { overlay.remove(); onConfirm(); };
        document.getElementById('confirmCancel').onclick = () => overlay.remove();
        overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
    },

    // ==================== 增强版 exportData（JSON备份）====================
    async exportDataBackup() {
        if (!await this.hasPermission('data.export')) {
            this.showToast('您没有导出数据的权限', 'error');
            return;
        }

        const users = await this.dbGetAll('users');
        const customers = await this.dbGetAll('customers');
        const scripts = await this.dbGetAll('scripts');
        const products = await this.dbGetAll('products');
        const visitRecords = await this.dbGetAll('visit_records');
        const settings = await this.dbGet('settings', 'main');
        const groups = await this.dbGetAll('permission_groups');

        const data = {
            version: '2.0',
            exportTime: new Date().toISOString(),
            users, customers, scripts, products, visitRecords,
            settings: settings || {},
            permission_groups: groups
        };

        const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `系统备份_${this.getDateString(new Date())}.json`;
        a.click();
        URL.revokeObjectURL(url);
        this.showToast('数据备份已导出', 'success');

        // 记录备份时间
        localStorage.setItem('crv_last_backup', new Date().toISOString());
        this.updateLastBackupDisplay();
    },

    updateLastBackupDisplay() {
        const el = document.getElementById('lastBackupTime');
        if (el) {
            const t = localStorage.getItem('crv_last_backup');
            el.textContent = t ? new Date(t).toLocaleString('zh-CN') : '从未备份';
        }
    },

    // ==================== 统计图表 ====================
    async renderCharts(filteredCustomers = null, filteredVisitRecords = null, startDate = null, endDate = null) {
        await this.renderMonthlyTrendChart(filteredCustomers, startDate, endDate);
        await this.renderVisitRateChart(filteredCustomers);
        await this.renderLevelDistChart(filteredCustomers);
        await this.renderVisitFrequencyChart(filteredVisitRecords, startDate, endDate);
        await this.renderVisitMethodChart(filteredVisitRecords);
    },

    async renderMonthlyTrendChart(filteredCustomers = null, startDate = null, endDate = null) {
        const el = document.getElementById('monthlyTrendChart');
        if (!el) return;

        let customers = filteredCustomers || await this.dbGetAll('customers');
        const activeCustomers = customers.filter(c => c.status === 'active');

        const now = new Date();
        const months = [];
        const counts = [];


        for (let i = 5; i >= 0; i--) {
            const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
            const monthStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
            months.push(`${d.getMonth() + 1}月`);

            // 如果有日期范围筛选，只统计范围内的
            if (startDate && endDate) {
                const monthStart = new Date(d.getFullYear(), d.getMonth(), 1);
                const monthEnd = new Date(d.getFullYear(), d.getMonth() + 1, 0);
                // 检查月份是否与筛选范围重叠
                if (monthStart <= endDate && monthEnd >= startDate) {
                    counts.push(activeCustomers.filter(c => {
                        if (!c.createdAt) return false;
                        const createdDate = new Date(c.createdAt);
                        return createdDate >= new Date(Math.max(startDate.getTime(), monthStart.getTime())) &&
                               createdDate <= new Date(Math.min(endDate.getTime(), monthEnd.getTime()));
                    }).length);
                } else {
                    counts.push(0);
                }
            } else {
                counts.push(activeCustomers.filter(c => c.createdAt && c.createdAt.startsWith(monthStr)).length);
            }
        }


        const chart = echarts.init(el);
        chart.setOption({
            title: { text: '近6个月新增客户', textStyle: { fontSize: 14, color: '#1F2937' } },
            tooltip: { trigger: 'axis' },
            xAxis: { type: 'category', data: months, axisLine: { lineStyle: { color: '#E5E7EB' } } },
            yAxis: { type: 'value', minInterval: 1, axisLine: { lineStyle: { color: '#E5E7EB' } } },
            series: [{
                data: counts, type: 'bar',
                itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    { offset: 0, color: '#667eea' }, { offset: 1, color: '#764ba2' }
                ]), borderRadius: [6, 6, 0, 0] },
                label: { show: true, position: 'top', fontSize: 12 }
            }],
            grid: { top: 50, right: 20, bottom: 30, left: 40 }
        });
        
        // 响应式
        window.addEventListener('resize', () => chart.resize());
    },

    async renderVisitRateChart(filteredCustomers = null) {
        const el = document.getElementById('visitRateChart');
        if (!el) return;

        const customers = filteredCustomers || await this.getCustomers();
        const activeCustomers = customers.filter(c => c.status === 'active');
        const today = this.getDateString(new Date());

        const overdueCount = activeCustomers.filter(c => c.nextVisitDate < today).length;
        const todayCount = activeCustomers.filter(c => c.nextVisitDate === today).length;
        const normalCount = activeCustomers.length - overdueCount - todayCount;

        const chart = echarts.init(el);
        chart.setOption({
            title: { text: '回访状态分布', textStyle: { fontSize: 14, color: '#1F2937' } },
            tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
            legend: { bottom: '5%', left: 'center', itemWidth: 12, itemHeight: 12 },
            series: [{
                type: 'pie', radius: ['40%', '70%'],
                data: [
                    { value: overdueCount, name: '已逾期', itemStyle: { color: '#EF4444' } },
                    { value: todayCount, name: '今日待访', itemStyle: { color: '#F59E0B' } },
                    { value: normalCount, name: '正常', itemStyle: { color: '#10B981' } }
                ],
                label: { show: false },
                emphasis: { label: { show: true, fontSize: 14, fontWeight: 'bold' } }
            }]
        });
        
        window.addEventListener('resize', () => chart.resize());
    },

    async renderLevelDistChart(filteredCustomers = null) {
        const el = document.getElementById('levelDistChart');
        if (!el) return;

        const customers = filteredCustomers || await this.getCustomers();
        const activeCustomers = customers.filter(c => c.status === 'active');
        const levelColors = { A: '#EF4444', B: '#F59E0B', C: '#10B981', D: '#6B7280' };
        const levelData = ['A', 'B', 'C', 'D'].map(l => ({
            value: activeCustomers.filter(c => c.level === l).length,
            name: l + '级客户',
            itemStyle: { color: levelColors[l] }
        }));

        const chart = echarts.init(el);
        chart.setOption({
            title: { text: '客户等级分布', textStyle: { fontSize: 14, color: '#1F2937' } },
            tooltip: { trigger: 'item', formatter: '{b}: {c}人 ({d}%)' },
            series: [{
                type: 'pie', radius: '65%',
                data: levelData,
                label: { formatter: '{b}\n{d}%', fontSize: 12 },
                emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0,0,0,0.3)' } }
            }]
        });
        window.addEventListener('resize', () => chart.resize());
    },

    // 回访频率分析图（近12周每周回访次数）
    async renderVisitFrequencyChart(filteredVisitRecords = null, startDate = null, endDate = null) {
        const el = document.getElementById('visitFrequencyChart');
        if (!el) return;

        let visitRecords = filteredVisitRecords || await this.dbGetAll('visit_records');

        // 按日期范围过滤
        if (startDate && endDate) {
            visitRecords = visitRecords.filter(r => {
                if (!r.createdAt) return false;
                const d = new Date(r.createdAt);
                return d >= startDate && d <= endDate;
            });
        }

        // 统计近12周回访频率
        const now = new Date();
        const weeks = [];
        const counts = [];

        for (let i = 11; i >= 0; i--) {
            const weekStart = new Date(now);
            weekStart.setDate(now.getDate() - i * 7 - now.getDay());
            weekStart.setHours(0, 0, 0, 0);
            const weekEnd = new Date(weekStart);
            weekEnd.setDate(weekStart.getDate() + 6);
            weekEnd.setHours(23, 59, 59, 999);

            const month = weekStart.getMonth() + 1;
            const day = weekStart.getDate();
            weeks.push(`${month}/${day}`);

            counts.push(visitRecords.filter(r => {
                if (!r.createdAt) return false;
                const d = new Date(r.createdAt);
                return d >= weekStart && d <= weekEnd;
            }).length);
        }

        const chartInstance = echarts.init(el);
        chartInstance.setOption({
            title: { text: '近12周回访频率', textStyle: { fontSize: 14, color: '#1F2937' } },
            tooltip: { trigger: 'axis', formatter: (params) => `第 ${params[0].name} 周：${params[0].value} 次` },
            xAxis: {
                type: 'category', data: weeks, boundaryGap: false,
                axisLabel: { fontSize: 11, color: '#6B7280' },
                axisLine: { lineStyle: { color: '#E5E7EB' } }
            },
            yAxis: { type: 'value', minInterval: 1, axisLine: { lineStyle: { color: '#E5E7EB' } } },
            series: [{
                data: counts, type: 'line', smooth: true,
                symbol: 'circle', symbolSize: 6,
                lineStyle: { color: '#10B981', width: 2 },
                itemStyle: { color: '#10B981' },
                areaStyle: {
                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: 'rgba(16,185,129,0.3)' },
                        { offset: 1, color: 'rgba(16,185,129,0.02)' }
                    ])
                },
                label: { show: false }
            }],
            grid: { top: 50, right: 20, bottom: 30, left: 40 }
        });
        window.addEventListener('resize', () => chartInstance.resize());
    },

    // 回访方式分布图
    async renderVisitMethodChart(filteredVisitRecords = null) {
        const el = document.getElementById('visitMethodChart');
        if (!el) return;

        const visitRecords = filteredVisitRecords || await this.dbGetAll('visit_records');

        const methodCounts = {};
        const methodOrder = ['电话', '微信', '上门拜访', '邮件', '视频通话', '其他'];
        const methodColors = ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#6B7280'];

        visitRecords.forEach(r => {
            const method = r.method || '其他';
            methodCounts[method] = (methodCounts[method] || 0) + 1;
        });

        const methods = methodOrder.filter(m => methodCounts[m] > 0);
        const counts = methods.map(m => methodCounts[m] || 0);
        const colors = methods.map((m, i) => methodColors[methodOrder.indexOf(m)] || '#9CA3AF');

        const chartInstance = echarts.init(el);
        chartInstance.setOption({
            title: { text: '回访方式分布', textStyle: { fontSize: 14, color: '#1F2937' } },
            tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
            xAxis: {
                type: 'category', data: methods,
                axisLabel: { fontSize: 12, color: '#6B7280' }
            },
            yAxis: { type: 'value', minInterval: 1 },
            series: [{
                type: 'bar',
                data: counts.map((v, i) => ({ value: v, itemStyle: { color: colors[i], borderRadius: [6, 6, 0, 0] } })),
                label: { show: true, position: 'top', fontSize: 12, color: '#374151' }
            }],
            grid: { top: 50, right: 20, bottom: 40, left: 40 }
        });
        window.addEventListener('resize', () => chartInstance.resize());
    },


    async requestNotificationPermission() {
        if ('Notification' in window && Notification.permission === 'default') {
            await Notification.requestPermission();
        }
    },

    sendBrowserNotification(title, body, customerId = null) {
        if ('Notification' in window && Notification.permission === 'granted') {
            const n = new Notification(title, {
                body,
                icon: 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">🔔</text></svg>',
                tag: customerId || 'crv-notification'
            });
            n.onclick = () => { window.focus(); n.close(); };
            setTimeout(() => n.close(), 8000);
        }
    },

    async checkAndSendVisitReminders() {
        const customers = await this.getCustomers();
        const today = this.getDateString(new Date());
        const activeCustomers = customers.filter(c => c.status === 'active');
        
        const todayCustomers = activeCustomers.filter(c => c.nextVisitDate === today);
        const overdueCustomers = activeCustomers.filter(c => c.nextVisitDate < today);
        
        // 仅在今天第一次加载时发送通知
        const lastNotifyDate = localStorage.getItem('crv_last_notify_date');
        if (lastNotifyDate === today) return;
        
        localStorage.setItem('crv_last_notify_date', today);
        
        if (todayCustomers.length > 0) {
            this.sendBrowserNotification(
                '📞 今日回访提醒',
                `您有 ${todayCustomers.length} 位客户需要今日回访，点击打开系统`
            );
        }
        if (overdueCustomers.length > 0) {
            setTimeout(() => {
                this.sendBrowserNotification(
                    '⚠️ 逾期回访提醒',
                    `有 ${overdueCustomers.length} 位客户回访已逾期，请尽快处理`
                );
            }, 2000);
        }
    },

    // ==================== 批量操作 ====================
    selectedCustomers: new Set(),
    
    toggleCustomerSelect(id) {
        if (this.selectedCustomers.has(id)) {
            this.selectedCustomers.delete(id);
        } else {
            this.selectedCustomers.add(id);
        }
        this.updateBatchToolbar();
    },

    toggleSelectAll(checked) {
        const checkboxes = document.querySelectorAll('.customer-select-cb');
        checkboxes.forEach(cb => {
            cb.checked = checked;
            if (checked) {
                this.selectedCustomers.add(cb.dataset.id);
            } else {
                this.selectedCustomers.delete(cb.dataset.id);
            }
        });
        this.updateBatchToolbar();
    },

    updateBatchToolbar() {
        const toolbar = document.getElementById('batchToolbar');
        if (!toolbar) return;
        const count = this.selectedCustomers.size;
        if (count > 0) {
            toolbar.style.display = 'flex';
            document.getElementById('batchCount').textContent = `已选 ${count} 项`;
        } else {
            toolbar.style.display = 'none';
        }
    },

    async batchUpdateLevel(level) {
        if (this.selectedCustomers.size === 0) return;
        const ids = [...this.selectedCustomers];
        const customers = await this.dbGetAll('customers');
        for (const c of customers) {
            if (ids.includes(c.id)) {
                c.level = level;
                await this.dbPut('customers', c);
            }
        }
        this.selectedCustomers.clear();
        this.updateBatchToolbar();
        await this.renderCustomerTable();
        this.showToast(`已将 ${ids.length} 位客户等级更新为 ${level}级`, 'success');
    },

    async batchDeleteCustomers() {
        if (this.selectedCustomers.size === 0) return;
        const ids = [...this.selectedCustomers];
        this.showConfirm('批量删除', `确定要删除选中的 ${ids.length} 位客户吗？此操作不可恢复！`, async () => {
            for (const id of ids) {
                await this.dbDelete('customers', id);
            }
            this.selectedCustomers.clear();
            this.updateBatchToolbar();
            await this.renderCustomerTable();
            this.showToast(`已删除 ${ids.length} 位客户`, 'success');
        }, 'danger');
    },

    async batchExportSelected() {
        if (this.selectedCustomers.size === 0) {
            this.showToast('请先选择要导出的客户', 'warning');
            return;
        }
        const ids = [...this.selectedCustomers];
        const allCustomers = await this.getCustomers();
        const users = await this.getAllUsers();

        const selected = allCustomers.filter(c => ids.includes(c.id));

        try {
            // 准备Excel数据
            const headers = ['姓名', '电话', '公司', '等级', '省份', '城市', '详细地址', '回访周期(天)', '经营范围', '客户标签', '下次回访日期', '状态', '备注', '归属用户', '创建时间'];
            const rows = selected.map(c => {
                // 获取用户名称
                const ownerUserNames = c.ownerUsers && c.ownerUsers.length > 0
                    ? c.ownerUsers.map(uid => {
                        const user = users.find(u => u.id === uid);
                        return user ? user.realName : '';
                    }).filter(Boolean).join('、')
                    : '';

                return {
                    '姓名': c.name,
                    '电话': c.phone,
                    '公司': c.company || '',
                    '等级': this.getLevelName(c.level),
                    '省份': c.province || '',
                    '城市': c.city || '',
                    '详细地址': c.address || '',
                    '回访周期(天)': c.returnVisitDays || 30,
                    '经营范围': c.businessScope && c.businessScope.length > 0 ? c.businessScope.join('、') : '',
                    '客户标签': c.tags && c.tags.length > 0 ? c.tags.join('、') : '',
                    '下次回访日期': c.nextVisitDate || '',
                    '状态': c.status === 'active' ? '正常' : '已停用',
                    '备注': c.remark || '',
                    '归属用户': ownerUserNames,
                    '创建时间': c.createdAt ? new Date(c.createdAt).toLocaleString('zh-CN') : ''
                };
            });

            // 创建工作簿
            const wb = XLSX.utils.book_new();

            // 创建工作表
            const ws = XLSX.utils.json_to_sheet(rows, { header: headers });

            // 设置列宽
            const colWidths = [
                { wch: 10 }, // 姓名
                { wch: 15 }, // 电话
                { wch: 20 }, // 公司
                { wch: 8 },  // 等级
                { wch: 12 }, // 省份
                { wch: 12 }, // 城市
                { wch: 30 }, // 详细地址
                { wch: 12 }, // 回访周期
                { wch: 20 }, // 经营范围
                { wch: 20 }, // 客户标签
                { wch: 15 }, // 下次回访日期
                { wch: 8 },  // 状态
                { wch: 30 }, // 备注
                { wch: 20 }, // 归属用户
                { wch: 20 }  // 创建时间
            ];
            ws['!cols'] = colWidths;

            // 添加工作表到工作簿
            XLSX.utils.book_append_sheet(wb, ws, '客户数据');

            // 生成Excel文件并下载
            const fileName = `选中客户_${this.getDateString(new Date())}.xlsx`;
            XLSX.writeFile(wb, fileName);

            this.showToast(`已导出 ${selected.length} 位客户数据`, 'success');
        } catch (e) {
            console.error('Excel导出失败:', e);
            this.showToast('Excel导出失败: ' + e.message, 'error');
        }
    },

    async enableBrowserNotify() {
        await this.requestNotificationPermission();
        if (Notification.permission === 'granted') {
            const btn = document.getElementById('enableNotifyBtn');
            const bar = document.getElementById('notifyStatusBar');
            if (btn) btn.style.display = 'none';
            if (bar) bar.style.display = 'block';
            this.showToast('桌面通知已开启', 'success');
            this.sendBrowserNotification('通知测试', '您已成功开启回访提醒通知！');
        } else if (Notification.permission === 'denied') {
            this.showToast('浏览器已拒绝通知权限，请在地址栏手动授权', 'error');
        }
    },

    checkPasswordStrength(password) {
        const bar = document.getElementById('passwordStrengthBar');
        const fill = document.getElementById('passwordStrengthFill');
        const text = document.getElementById('passwordStrengthText');
        
        if (!bar || !fill || !text) return;
        
        if (!password) {
            bar.style.display = 'none';
            text.textContent = '';
            return;
        }
        
        bar.style.display = 'block';
        
        let score = 0;
        if (password.length >= 6) score++;
        if (password.length >= 10) score++;
        if (/[A-Z]/.test(password)) score++;
        if (/[0-9]/.test(password)) score++;
        if (/[^A-Za-z0-9]/.test(password)) score++;
        
        const levels = [
            { width: '20%', color: '#EF4444', label: '非常弱' },
            { width: '40%', color: '#F97316', label: '弱' },
            { width: '60%', color: '#F59E0B', label: '中等' },
            { width: '80%', color: '#84CC16', label: '强' },
            { width: '100%', color: '#10B981', label: '非常强' }
        ];
        
        const level = levels[Math.min(score - 1, 4)] || levels[0];
        fill.style.width = level.width;
        fill.style.background = level.color;
        text.textContent = `密码强度: ${level.label}`;
        text.style.color = level.color;
    },

    // ==================== 手机端专用功能 ====================

    // 显示今日回访列表
    async showTodayVisits() {
        const today = this.getDateString(new Date());
        const customers = await this.getCustomers();
        const todayCustomers = customers.filter(c => 
            c.status === 'active' && c.nextVisitDate === today
        );

        if (todayCustomers.length === 0) {
            this.showToast('今日没有需要回访的客户', 'info');
            return;
        }

        // 创建手机端弹窗显示今日回访
        const modal = document.createElement('div');
        modal.className = 'modal active';
        modal.id = 'todayVisitsModal';
        modal.innerHTML = `
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3>今日回访 (${todayCustomers.length})</h3>
                        <button class="modal-close" onclick="document.getElementById('todayVisitsModal').remove()">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                    <div class="modal-body">
                        <div class="mobile-list">
                            ${todayCustomers.map(c => `
                                <div class="customer-card" onclick="app.showVisitModal('${c.id}'); document.getElementById('todayVisitsModal').remove();">
                                    <div class="customer-card-header">
                                        <div class="customer-card-title">
                                            <span class="level-tag ${c.level}">${c.level}</span>
                                            <h3>${c.name}</h3>
                                        </div>
                                    </div>
                                    <div class="customer-card-body">
                                        <div class="info-row">
                                            <span><i class="fas fa-phone"></i> ${c.phone}</span>
                                        </div>
                                        <div class="info-row">
                                            <span><i class="fas fa-building"></i> ${c.company || '-'}</span>
                                        </div>
                                    </div>
                                </div>
                            `).join('')}
                        </div>
                    </div>
                </div>
            </div>
        `;
        document.body.appendChild(modal);
    },

    // 显示更多菜单（手机端）
    showMoreMenu() {
        const menuItems = [
            { icon: 'fa-tags', text: '客户分类', action: () => this.navigateTo('classify') },
            { icon: 'fa-comment-dots', text: '回访话术', action: () => this.navigateTo('scripts') },
            { icon: 'fa-box-open', text: '产品展示', action: () => this.navigateTo('products') },
            { icon: 'fa-cog', text: '系统设置', action: () => this.navigateTo('settings') },
            { icon: 'fa-sign-out-alt', text: '退出登录', action: () => this.handleLogout() }
        ];

        // 管理员额外菜单
        if (this.currentUser && this.currentUser.role === 'admin') {
            menuItems.splice(4, 0, 
                { icon: 'fa-user-cog', text: '用户权限', action: () => this.navigateTo('users') },
                { icon: 'fa-chart-bar', text: '数据统计', action: () => this.navigateTo('statistics') }
            );
        }

        const modal = document.createElement('div');
        modal.className = 'modal active';
        modal.id = 'moreMenuModal';
        modal.innerHTML = `
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3>更多功能</h3>
                        <button class="modal-close" onclick="document.getElementById('moreMenuModal').remove()">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                    <div class="modal-body">
                        <div class="quick-actions">
                            ${menuItems.map(item => `
                                <div class="quick-action-item" onclick="(${item.action.toString()})(); document.getElementById('moreMenuModal').remove();">
                                    <i class="fas ${item.icon}"></i>
                                    <span>${item.text}</span>
                                </div>
                            `).join('')}
                        </div>
                    </div>
                </div>
            </div>
        `;
        document.body.appendChild(modal);
    },

    // ==================== 工具函数 ====================

    openModal(modalId) {
        document.getElementById(modalId).classList.add('active');
    },

    closeModal(modalId) {
        document.getElementById(modalId).classList.remove('active');
    },

    generateId() {
        return 'id_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
    },

    getDateString(date) {
        const d = new Date(date);
        return d.toISOString().split('T')[0];
    },

    getDaysDiff(date1, date2) {
        const d1 = new Date(date1);
        const d2 = new Date(date2);
        return Math.ceil((d2 - d1) / (1000 * 60 * 60 * 24));
    },

    capitalize(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    },

    getRoleName(role) {
        const names = {
            admin: '管理员',
            manager: '经理',
            staff: '员工'
        };
        return names[role] || role;
    },

    getLevelName(level) {
        const names = {
            A: 'A级 - 重点客户',
            B: 'B级 - 重要客户',
            C: 'C级 - 普通客户',
            D: 'D级 - 潜在客户'
        };
        return names[level] || level;
    },

    // ==================== 云同步接口 ====================
    // 导出全量数据到文件（供同步工具读取上传到 MySQL）
    async syncExportToFile() {
        if (!window.electronAPI) {
            this.showToast('仅 Electron 客户端支持云同步', 'error');
            return;
        }
        try {
            this.showToast('正在准备导出数据...', 'info');
            const [users, customers, scripts, products, visitRecords, groups, schemes] = await Promise.all([
                this.dbGetAll('users'),
                this.dbGetAll('customers'),
                this.dbGetAll('scripts'),
                this.dbGetAll('products'),
                this.dbGetAll('visit_records'),
                this.dbGetAll('permission_groups'),
                this.dbGetAll('industry_schemes')
            ]);
            const settings = await this.dbGet('settings', 'main');
            const data = {
                version: '2.0',
                exportTime: new Date().toISOString(),
                users, customers, scripts, products,
                visit_records: visitRecords,
                permission_groups: groups,
                industry_schemes: schemes,
                settings: settings || {}
            };
            const result = await window.electronAPI.syncSaveExport(data);
            if (result.success) {
                this.showToast('数据已导出，请打开同步工具执行上传', 'success');
            } else {
                this.showToast('导出失败: ' + result.error, 'error');
            }
        } catch (e) {
            this.showToast('导出异常: ' + e.message, 'error');
        }
    },

    // 从文件导入数据（同步工具从 MySQL 下载后调用）
    async syncImportFromFile() {
        if (!window.electronAPI) {
            this.showToast('仅 Electron 客户端支持云同步', 'error');
            return;
        }
        try {
            const result = await window.electronAPI.syncLoadImport();
            if (!result.success) {
                this.showToast(result.error || '没有待导入的数据', 'warning');
                return;
            }
            const data = result.data;
            this.showToast('正在导入数据，请稍候...', 'info');
            const tables = ['users', 'customers', 'scripts', 'products', 'permission_groups', 'industry_schemes'];
            const tableMap = {
                users: data.users || [],
                customers: data.customers || [],
                scripts: data.scripts || [],
                products: data.products || [],
                permission_groups: data.permission_groups || [],
                industry_schemes: data.industry_schemes || [],
                visit_records: data.visit_records || []
            };
            for (const table of [...tables, 'visit_records']) {
                const items = tableMap[table] || [];
                if (items.length === 0) continue;
                await this.dbBulkPut(table, items);
            }
            if (data.settings && data.settings.id) {
                await this.dbPut('settings', data.settings);
            }
            this.showToast('云端数据导入成功！', 'success');
            // 刷新当前页面
            setTimeout(() => { this.navigateTo(this.currentPage || 'dashboard'); }, 800);
        } catch (e) {
            this.showToast('导入异常: ' + e.message, 'error');
        }
    }
};

// 初始化应用
document.addEventListener('DOMContentLoaded', () => {
    app.init();
});

// 点击模态框外部关闭
document.querySelectorAll('.modal').forEach(modal => {
    modal.addEventListener('click', (e) => {
        if (e.target === modal) {
            modal.classList.remove('active');
        }
    });
});
