"""
Flask 服务器 - 智途投送电脑端
提供静态文件服务 + REST API（士兵位置、危险区域）
浏览器通过 roslibjs 直接连接 rosbridge_server，无需 Python 后端处理无人机逻辑
"""

import os
from datetime import datetime
from flask import Flask, send_from_directory, request, jsonify
from flask_cors import CORS

# 项目根目录（server 的上级目录）
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

app = Flask(__name__, static_folder=BASE_DIR)
CORS(app)  # 允许跨域请求，支持单兵APP访问

# ---- 内存数据存储 ----
soldiers = {}       # { soldier_id: { id, name, lat, lng, updated_at } }
danger_zones = []   # [ { id, lat, lng, radius, description, created_at } ]
_demands = []       # [ { id, soldier_id, soldier_name, type, quantity, unit, urgency, status, created_at } ]
_demand_id_counter = 0
_drop_points = [    # 推荐投放点（演示数据）
    {"id": 1, "name": "安全点 #1", "safety_score": 92, "distance": 5, "reason": "深掩体保护，视角盲区", "lat": 30.0050, "lng": 120.0030},
    {"id": 2, "name": "安全点 #2", "safety_score": 85, "distance": 12, "reason": "钢筋混凝土建筑内部", "lat": 30.0055, "lng": 120.0035},
    {"id": 3, "name": "陷阱点 #3", "safety_score": 35, "distance": 20, "reason": "孤立断墙，成瞄准点", "lat": 30.0060, "lng": 120.0040}
]
_tasks = {}         # { soldier_id: task }
_drone_status = {   # 无人机实时状态（演示数据）
    "drone_id": "无人机-01",
    "task_id": "#001",
    "status": "飞行中",
    "position": "A区街角12号",
    "battery": 85,
    "eta": "12:30",
    "speed": 8.5,
    "altitude": 15,
    "distance": 500,
    "temperature": 38,
    "lat": 30.0040,
    "lng": 120.0025
}
_drone_logs = [     # 无人机动态日志
    {"time": "12:25:30", "message": "到达投放点"},
    {"time": "12:20:45", "message": "接收任务指令"},
    {"time": "12:10:00", "message": "任务分配"}
]
_sos_alerts = []    # 求救记录
_accounts = {       # 士兵账号 { soldier_id: { password, name, unit, role } }
    "soldier_001": { "password": "123456", "name": "张三", "unit": "第3步兵师/1连", "role": "狙击手" },
    "soldier_002": { "password": "123456", "name": "李四", "unit": "第3步兵师/2连", "role": "机枪手" },
    "soldier_003": { "password": "123456", "name": "王五", "unit": "第3步兵师/3连", "role": "通讯员" }
}
_tasks = {}         # { soldier_id: { id, status, progress, eta, ... } }
_task_id_counter = 0
_danger_id_counter = 0


# ===== 静态文件路由 =====

@app.route("/")
def index():
    return send_from_directory(BASE_DIR, "index.html")


@app.route("/css/<path:filename>")
def css_files(filename):
    return send_from_directory(os.path.join(BASE_DIR, "css"), filename)


@app.route("/js/<path:filename>")
def js_files(filename):
    return send_from_directory(os.path.join(BASE_DIR, "js"), filename)


# ===== REST API: 士兵位置 =====

@app.route("/api/soldier/location", methods=["POST"])
def update_soldier_location():
    data = request.get_json(force=True)
    sid = data.get("id")
    if not sid:
        return jsonify({"ok": False, "error": "missing id"}), 400

    soldiers[sid] = {
        "id": sid,
        "name": data.get("name", sid),
        "lat": float(data.get("lat", 0)),
        "lng": float(data.get("lng", 0)),
        "updated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    return jsonify({"ok": True})


@app.route("/api/soldiers", methods=["GET"])
def get_soldiers():
    return jsonify({"soldiers": list(soldiers.values())})


# ===== REST API: 危险区域 =====

@app.route("/api/danger-zones", methods=["GET"])
def get_danger_zones():
    return jsonify({"danger_zones": danger_zones})


@app.route("/api/danger-zones", methods=["POST"])
def add_danger_zone():
    global _danger_id_counter
    data = request.get_json(force=True)
    _danger_id_counter += 1
    zone = {
        "id": _danger_id_counter,
        "lat": float(data.get("lat", 0)),
        "lng": float(data.get("lng", 0)),
        "radius": float(data.get("radius", 50)),
        "description": data.get("description", "危险区域"),
        "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    danger_zones.append(zone)
    return jsonify({"ok": True, "id": zone["id"]})


# ===== REST API: 物资需求（单兵APP） =====

@app.route("/api/demand", methods=["POST"])
def post_demand():
    global _demand_id_counter
    data = request.get_json(force=True)
    _demand_id_counter += 1

    # 获取投放点坐标（如果有）
    drop_point = data.get("drop_point") or {}
    lat = float(drop_point.get("lat", 0)) if isinstance(drop_point, dict) else 0
    lng = float(drop_point.get("lng", 0)) if isinstance(drop_point, dict) else 0

    # 如果APP没传坐标，尝试从士兵位置获取
    soldier_id = data.get("soldier_id", "unknown")
    if lat == 0 and lng == 0 and soldier_id in soldiers:
        lat = soldiers[soldier_id].get("lat", 0)
        lng = soldiers[soldier_id].get("lng", 0)

    # 构建物资清单描述
    qty = int(data.get("quantity", 0))
    unit = data.get("unit", "个")
    item_type = data.get("type", "未知")
    items = f"{item_type} × {qty}{unit}"

    demand = {
        "id": "REQ-" + str(_demand_id_counter).zfill(3),
        "soldier_id": soldier_id,
        "soldier_name": data.get("soldier_name", "未知"),
        "type": item_type + "补给",
        "items": items,
        "quantity": qty,
        "unit": unit,
        "urgency": data.get("urgency", "一般"),
        "status": "待处理",
        "lat": lat,
        "lng": lng,
        "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    _demands.append(demand)
    return jsonify({"ok": True, "id": demand["id"]})


@app.route("/api/demands", methods=["GET"])
def get_demands():
    soldier_id = request.args.get("soldier_id")
    if soldier_id:
        return jsonify({"demands": [d for d in _demands if d["soldier_id"] == soldier_id]})
    # 返回所有待处理需求（供电脑端使用）
    pending = [d for d in _demands if d["status"] == "待处理"]
    return jsonify({"demands": pending})


@app.route("/api/demands/<int:demand_id>", methods=["GET"])
def get_demand(demand_id):
    for d in _demands:
        if d["id"] == demand_id:
            return jsonify({"demand": d})
    return jsonify({"ok": False, "error": "not found"}), 404


# ===== REST API: 投放点 =====

@app.route("/api/drop-points", methods=["GET"])
def get_drop_points():
    return jsonify({"drop_points": _drop_points})


@app.route("/api/drop-point", methods=["POST"])
def post_drop_point():
    data = request.get_json(force=True)
    # 记录士兵选择的投放点
    return jsonify({"ok": True})


# ===== REST API: 任务状态 =====

@app.route("/api/task/dispatch", methods=["POST"])
def dispatch_task():
    """电脑端调度任务时调用"""
    global _task_id_counter
    data = request.get_json(force=True)
    soldier_id = data.get("soldier_id", "unknown")
    _task_id_counter += 1

    task = {
        "id": "#" + str(_task_id_counter).zfill(3),
        "soldier_id": soldier_id,
        "soldier_name": data.get("soldier_name", "未知"),
        "type": data.get("type", "未知"),
        "status": "执行中",
        "progress": 0,
        "eta": "计算中...",
        "remain_time": "计算中...",
        "start_name": data.get("start_name", "后方阵地"),
        "target_name": data.get("target_name", "目标位置"),
        "start_lat": float(data.get("start_lat", 30.0)),
        "start_lng": float(data.get("start_lng", 120.0)),
        "end_lat": float(data.get("end_lat", 30.0)),
        "end_lng": float(data.get("end_lng", 120.0)),
        "safety_score": data.get("safety_score", 90),
        "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    _tasks[soldier_id] = task

    # 更新需求状态为"已调度"
    demand_id = data.get("demand_id")
    if demand_id:
        for d in _demands:
            if d["id"] == demand_id:
                d["status"] = "已调度"
                break

    return jsonify({"ok": True, "task": task})


@app.route("/api/task/current", methods=["GET"])
def get_current_task():
    soldier_id = request.args.get("soldier_id", "soldier_001")
    task = _tasks.get(soldier_id)
    if not task:
        # 没有任务时返回模拟数据
        task = {
            "id": "#--",
            "status": "无任务",
            "progress": 0,
            "eta": "--",
            "remain_time": "--",
            "start_name": "--",
            "target_name": "--",
            "safety_score": 0
        }
    return jsonify({"task": task})


@app.route("/api/task/update", methods=["POST"])
def update_task():
    """更新任务状态（进度、ETA等）"""
    data = request.get_json(force=True)
    soldier_id = data.get("soldier_id", "unknown")
    task = _tasks.get(soldier_id)
    if not task:
        return jsonify({"ok": False, "error": "无进行中的任务"}), 404

    if "progress" in data:
        task["progress"] = int(data["progress"])
    if "status" in data:
        task["status"] = data["status"]
    if "eta" in data:
        task["eta"] = data["eta"]
    if "remain_time" in data:
        task["remain_time"] = data["remain_time"]

    return jsonify({"ok": True, "task": task})


# ===== REST API: 无人机状态 =====

@app.route("/api/drone/status", methods=["GET"])
def get_drone_status():
    return jsonify({"status": _drone_status})


@app.route("/api/drone/logs", methods=["GET"])
def get_drone_logs():
    return jsonify({"logs": _drone_logs})


# ===== REST API: SOS求救 =====

@app.route("/api/sos", methods=["POST"])
def post_sos():
    data = request.get_json(force=True)
    alert = {
        "soldier_id": data.get("soldier_id", "unknown"),
        "soldier_name": data.get("soldier_name", "未知"),
        "lat": float(data.get("lat", 0)),
        "lng": float(data.get("lng", 0)),
        "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "handled": False
    }
    _sos_alerts.append(alert)
    # 同时标记为危险区域
    global _danger_id_counter
    _danger_id_counter += 1
    danger_zones.append({
        "id": _danger_id_counter,
        "lat": alert["lat"],
        "lng": alert["lng"],
        "radius": 100,
        "description": f"士兵求救: {alert['soldier_name']}",
        "created_at": alert["time"]
    })
    return jsonify({"ok": True, "alert_id": len(_sos_alerts)})


# ===== REST API: 账号系统 =====

@app.route("/api/auth/register", methods=["POST"])
def auth_register():
    data = request.get_json(force=True)
    sid = data.get("soldier_id", "").strip()
    pwd = data.get("password", "").strip()
    name = data.get("name", "").strip()
    unit = data.get("unit", "未知单位").strip()
    role = data.get("role", "步兵").strip()

    if not sid or not pwd or not name:
        return jsonify({"ok": False, "error": "士兵编号、密码、姓名不能为空"}), 400
    if sid in _accounts:
        return jsonify({"ok": False, "error": "该士兵编号已注册"}), 409

    _accounts[sid] = {
        "password": pwd,
        "name": name,
        "unit": unit,
        "role": role
    }
    save_accounts()  # 添加这一行
    return jsonify({"ok": True, "message": "注册成功"})


@app.route("/api/auth/login", methods=["POST"])
def auth_login():
    data = request.get_json(force=True)
    sid = data.get("soldier_id", "").strip()
    pwd = data.get("password", "").strip()

    account = _accounts.get(sid)
    if not account:
        return jsonify({"ok": False, "error": "士兵编号不存在"}), 404
    if account["password"] != pwd:
        return jsonify({"ok": False, "error": "密码错误"}), 401

    return jsonify({
        "ok": True,
        "soldier_id": sid,
        "name": account["name"],
        "unit": account["unit"],
        "role": account["role"]
    })


@app.route("/api/auth/accounts", methods=["GET"])
def get_accounts():
    return jsonify({
        "accounts": [
            {"soldier_id": k, "name": v["name"], "unit": v["unit"], "role": v["role"]}
            for k, v in _accounts.items()
        ]
    })

@app.route("/api/auth/change-password", methods=["POST"])
def change_password():
    data = request.get_json(force=True)
    sid = data.get("soldier_id", "").strip()
    old_pwd = data.get("old_password", "").strip()
    new_pwd = data.get("new_password", "").strip()
    
    if not sid or not old_pwd or not new_pwd:
        return jsonify({"ok": False, "error": "所有字段都不能为空"}), 400
    
    account = _accounts.get(sid)
    if not account:
        return jsonify({"ok": False, "error": "用户不存在"}), 404
    
    if account["password"] != old_pwd:
        return jsonify({"ok": False, "error": "原密码错误"}), 401
    
    # 更新密码
    account["password"] = new_pwd
    save_accounts()  # 添加这一行
    return jsonify({"ok": True, "message": "密码修改成功"})

if __name__ == "__main__":
    import sys
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    print("=" * 50)
    print("  智途投送 - 物流保障系统")
    print("  http://localhost:5000")
    print("  实机 rosbridge: ws://192.168.1.14:9090")
    print("=" * 50)
    app.run(host="0.0.0.0", port=5000, debug=False)
