from flask import jsonify, request, send_file, session, current_app
from flask_login import login_required, current_user
from scripts.update.zte import LoginClient
from scripts.models import db, Device, WorkOrder, Channel
from datetime import datetime
from sqlalchemy import text, create_engine
import hashlib
import pymysql
import io
import os


def init_device_routes(app):
    @app.route('/sync_offline_devices', methods=['POST'])
    @login_required
    def sync_offline_devices():
        allowed_roles = ['装维员', '统计员', '管理员', 'admin']
        if current_user.role not in allowed_roles and current_user.name != 'Admin':
            app.logger.warning(f'未授权访问：用户 {current_user.name} 尝试同步离线设备')
            return jsonify({'success': False, 'message': '没有权限执行此操作'})
        
        try:
            app.logger.info(f'用户 {current_user.name} 开始同步离线设备')
            # 从配置中获取数据库连接信息
            db_config = current_app.config['KEY110_DB']
            conn = pymysql.connect(**db_config)
            
            cursor = conn.cursor()
            
            # 获取所有教学点的状态
            cursor.execute("""
                SELECT 教学点名称, 连通状态
                FROM IP数据
            """)
            
            schools = cursor.fetchall()
            
            # 分别处理在线和离线的教学点
            offline_school_names = [school[0].strip().replace('  ', ' ') for school in schools if school[1] == '离线']
            online_school_names = [school[0].strip().replace('  ', ' ') for school in schools if school[1] == '在线']
            
            # 关闭1key110数据库连接
            cursor.close()
            conn.close()
            
            # 处理恢复在线的设备
            online_devices = Device.query.filter(
                Device.device_id.in_(online_school_names),
                Device.is_normal == False  # 当前状态为故障的设备
            ).all()
            
            # 删除恢复在线设备的在途工单
            recovered_count = 0
            for device in online_devices:
                # 查找并删除该设备的在途工单
                pending_orders = WorkOrder.query.filter_by(
                    device_id=device.device_id,
                    status='待处理'
                ).all()
                
                for order in pending_orders:
                    db.session.delete(order)
                    recovered_count += 1
                
                # 更新设备状态为正常
                device.is_normal = True
                db.session.add(device)
            
            # 处理离线设备
            offline_devices = Device.query.filter(
                Device.device_id.in_(offline_school_names),
                Device.in_use == True,
                Device.is_normal == True
            ).all()
                    
            # 生成工单号
            today = datetime.now().strftime('%Y%m%d')
            last_work_order = WorkOrder.query.filter(
                WorkOrder.order_id.like(f'{today}%')
            ).order_by(WorkOrder.order_id.desc()).first()
            
            start_number = int(last_work_order.order_id[-4:]) + 1 if last_work_order else 1
            
            # 创建工单
            created_count = 0
            for index, device in enumerate(offline_devices):
                # 检查是否已有在途工单
                existing_order = WorkOrder.query.filter_by(
                    device_id=device.device_id,
                    status='待处理'
                ).first()
                
                if existing_order:
                    continue
                    
                current_number = start_number + index
                new_number = f"{today}{str(current_number).zfill(4)}"
                
                work_order = WorkOrder(
                    order_id=new_number,
                    device_id=device.device_id,
                    dispatch_time=datetime.now(),
                    status='待处理',
                    branch=device.branch
                )
                
                db.session.add(work_order)
                device.is_normal = False
                db.session.add(device)
                created_count += 1
            
            db.session.commit()
            
            app.logger.info(f'同步完成：创建了 {created_count} 个工单，恢复了 {recovered_count} 个设备')
            return jsonify({
                'success': True,
                'count': created_count
            })
            
        except Exception as e:
            app.logger.error(f'同步离线设备失败：{str(e)}')
            return jsonify({
                'success': False,
                'message': str(e)
            })

    @app.route('/check_existing_orders', methods=['POST'])
    @login_required
    def check_existing_orders():
        device_ids = request.json.get('device_ids', [])
        app.logger.info(f'用户 {current_user.name} 检查设备工单状态，设备数量：{len(device_ids)}')
        
        # 查询设备状态
        existing_devices = Device.query.filter(
            Device.device_id.in_(device_ids),
            Device.is_normal == False  # 检查设备是否处于故障状态
        ).with_entities(Device.device_id).all()
        
        # 提取设备ID列表
        existing_device_ids = [device.device_id for device in existing_devices]
        app.logger.info(f'发现 {len(existing_device_ids)} 个设备存在故障工单')
        
        return jsonify({'existing_devices': existing_device_ids})

    @app.route('/get_captcha', methods=['GET'])
    def get_captcha():
        app.logger.info('用户请求验证码')
        try:
            client = LoginClient()
            cid = client.get_captcha()
            # 将 cid 存储在 session 中供后续使用
            session['zte_cid'] = cid
            
            # 读取验证码图片并返回给前端
            captcha_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 
                                    'static', 'captcha.png')
            with open(captcha_path, "rb") as f:
                app.logger.info('验证码获取成功')
                return send_file(
                    io.BytesIO(f.read()),
                    mimetype='image/png'
                )
        except Exception as e:
            app.logger.error(f'获取验证码失败：{str(e)}')
            return jsonify({'success': False, 'message': '获取验证码失败'})

    @app.route('/sync_camera_step1', methods=['POST'])
    def sync_camera_step1():
        try:
            app.logger.info(f'用户 {current_user.name if current_user else "未登录"} 开始同步摄像头第一步')
            data = request.get_json()
            captcha = data.get('captcha')
            cid = session.get('zte_cid')
            
            if not captcha or not cid:
                app.logger.warning('同步摄像头失败：验证码或会话ID缺失')
                return jsonify({'success': False, 'message': 'Invalid request'})
            
            client = LoginClient()
            # 登录
            app.logger.info('尝试登录中兴平台')
            login_result = client.login(
                account="DHDX001",
                password=hashlib.sha256("Root1234#".encode()).hexdigest(),
                validcode=captcha,
                cid=cid
            )
            
            if login_result.get("result") != 0:
                app.logger.warning('登录中兴平台失败：验证码错误')
                return jsonify({'success': False, 'message': 'INVALID_CAPTCHA'})
            
            token = login_result.get("token")
            app.logger.info('登录成功，开始获取在线信息')
            # 获取在线信息
            online_info = client.get_online_info(token)
            
            if online_info.get("result") == 0:
                rows = online_info.get("rows", [])
                updated_count = 0
                offline_count = 0
                
                app.logger.info(f'获取到 {len(rows)} 个设备信息，开始更新数据库')
                # 更新 channels 表
                for row in rows:
                    db.session.execute(
                        text("""
                            INSERT INTO channels (puid, pu_name, status)
                            VALUES (:puid, :pu_name, :status)
                            ON DUPLICATE KEY UPDATE
                            pu_name = :pu_name, status = :status
                        """),
                        {
                            'puid': row['puid'],
                            'pu_name': row['pu_name'],
                            'status': row['status']
                        }
                    )
                    updated_count += 1
                    if row['status'] != 'online':
                        offline_count += 1
                
                db.session.commit()
                app.logger.info(f'数据库更新完成，更新了 {updated_count} 条记录，其中离线设备 {offline_count} 个')
                return jsonify({
                    'success': True,
                    'updated_count': updated_count,
                    'offline_count': offline_count
                })
            
            app.logger.error('获取在线信息失败')
            return jsonify({'success': False, 'message': 'Failed to get online info'})
            
        except Exception as e:
            app.logger.error(f'同步摄像头步骤1失败：{str(e)}')
            return jsonify({'success': False, 'message': str(e)})

    @app.route('/sync_camera_step2', methods=['POST'])
    def sync_camera_step2():
        try:
            app.logger.info(f'用户 {current_user.name if current_user else "未登录"} 开始同步摄像头第二步')
            # 更新设备状态
            devices = Device.query.filter(
                Device.puid.isnot(None),
                Device.in_use == True  # 添加这个条件，只检查在用设备
            ).all()
            app.logger.info(f'查询到 {len(devices)} 个需要同步的设备')
            offline_devices = []
            
            for device in devices:
                channel = db.session.query(Channel).filter_by(puid=device.puid).first()
                if channel and channel.status != 'online':
                    device.is_normal = 0
                    # 检查是否已有在途工单
                    existing_order = WorkOrder.query.filter_by(
                        device_id=device.device_id,
                        status='待处理'
                    ).first()
                    
                    if not existing_order:  # 只添加没有在途工单的设备
                        offline_devices.append(device)
            
            db.session.commit()
            app.logger.info(f'发现 {len(offline_devices)} 个离线设备需要创建工单')
            
            # 为离线设备创建工单
            created_count = 0
            if offline_devices:
                today = datetime.now().strftime('%Y%m%d')
                last_work_order = WorkOrder.query.filter(
                    WorkOrder.order_id.like(f'{today}%')
                ).order_by(WorkOrder.order_id.desc()).first()
                
                start_number = int(last_work_order.order_id[-4:]) + 1 if last_work_order else 1
                
                for index, device in enumerate(offline_devices):
                    order_id = f"{today}{str(start_number + index).zfill(4)}"
                    work_order = WorkOrder(
                        order_id=order_id,
                        device_id=device.device_id,
                        status='待处理',
                        dispatch_time=datetime.now(),
                        branch=device.branch  # 添加支局信息
                    )
                    db.session.add(work_order)
                    created_count += 1
                
                db.session.commit()
                app.logger.info(f'成功创建 {created_count} 个工单')
            
            return jsonify({
                'success': True,
                'count': created_count
            })
            
        except Exception as e:
            app.logger.error(f'同步摄像头步骤2失败：{str(e)}')
            return jsonify({'success': False, 'message': str(e)})