//
//  HomeMenuRouter.swift
//  suixinkan
//
//  Created by Codex on 2026/6/22.
//

import Foundation
import os

/// 首页菜单路由器，将后端权限 URI 映射为 iOS 内部路由。
enum HomeMenuRouter {
    private static let titleMap: [String: String] = [
        "basic_info": "基本信息",
        "space_settings": "空间设置",
        "album_list": "相册管理",
        "album_trailer": "相册预览上传",
        "photographer_stats": "数据统计",
        "photographer_orders": "订单管理",
        "/scenic-order-manage": "景区订单",
        "verification_order": "核销订单",
        "wallet": "我的钱包",
        "cloud_management": "相册云盘",
        "cloud_storage_transit": "传输管理",
        "asset_management": "素材管理",
        "material_upload": "上传素材",
        "task_management": "任务管理",
        "task_management_editor": "任务管理",
        "task_create": "发布任务",
        "schedule_management": "日程管理",
        "system_settings": "设置中心",
        "message_center": "消息中心",
        "checkin_points": "打卡点管理",
        "sample_management": "样片管理",
        "sample_upload": "上传样片",
        "live_stream_management": "直播管理",
        "live_album": "直播相册",
        "scenicselection": "景区选择",
        "scenicapplication": "景区申请",
        "permission_apply": "权限申请",
        "permission_apply_status": "权限申请状态",
        "scenic_settlement": "景区结算",
        "scenic_settlement_review": "结算审核",
        "pm": "项目管理",
        "pm_manager": "项目管理",
        "project_edit": "项目编辑",
        "location_report": "位置上报",
        "registration_invitation": "注册邀请",
        "store": "店铺管理",
        "fly": "飞行管理",
        "pilot_cert": "飞手认证",
        "pilot_controller": "飞控",
        "/scenic-queue": "排队管理",
        "queue_management": "排队管理",
        "operating-area": "运营区域",
        "payment_collection": "立即收款",
        "payment_qr": "收款码",
        "payment_code": "收款码",
        "deposit_order_detail": "押金订单详情",
        "deposit_order": "押金订单详情",
        "deposit_order_shooting_info": "押金拍摄信息",
        "withdrawal_audit": "提现审核",
        "location_report_history": "定位上报历史",
        "photographer_invite": "邀请摄影师",
        "invite_record": "邀请记录",
        "more_functions": "更多功能"
    ]

    /// 根据权限 URI 解析跳转目标。
    static func resolve(uri: String, title: String) -> HomeMenuResolvedRoute {
        switch uri {
        case "photographer_orders", "/scenic-order-manage":
            return .orders(.storeOrders)
        case "verification_order":
            return .orders(.verificationOrders)
        case "photographer_stats":
            return .tab(.statistics)
        case "space_settings", "basic_info":
            return .destination(.profileSpace)
        case "system_settings":
            return .destination(.settings)
        case "scenicselection":
            return .destination(.scenicSelection)
        case "permission_apply":
            return .destination(.permissionApply)
        case "permission_apply_status":
            return .destination(.permissionApplyStatus)
        case "scenicapplication":
            return .destination(.scenicApplication)
        case "wallet":
            return .destination(.wallet)
        case "payment_collection", "payment_qr", "payment_code":
            return .destination(.paymentCollection)
        case "store", "more_functions":
            return .destination(.moreFunctions)
        case "fly", "pilot_controller":
            return .unsupported(
                uri: uri,
                title: title.isEmpty ? self.title(for: uri) : title,
                reason: "DJI/飞控模块已明确不纳入 iOS 迁移和后续开发范围。"
            )
        case "message_center",
             "/scenic-queue",
             "queue_management",
             "deposit_order_detail",
             "deposit_order",
             "deposit_order_shooting_info",
             "withdrawal_audit",
             "task_management",
             "task_management_editor",
             "task_create",
             "schedule_management",
             "checkin_points",
             "pm",
             "pm_manager",
             "project_edit",
             "cloud_management",
             "cloud_storage_transit",
             "album_list",
             "album_trailer",
             "asset_management",
             "material_upload",
             "sample_management",
             "sample_upload",
             "live_stream_management",
             "live_album",
             "scenic_settlement",
             "scenic_settlement_review",
             "operating-area",
             "location_report_history",
             "location_report",
             "registration_invitation",
             "photographer_invite",
             "invite_record",
             "pilot_cert":
            let resolvedTitle = title.isEmpty ? self.title(for: uri) : title
            return .destination(.modulePlaceholder(uri: uri, title: resolvedTitle))
        default:
            return .placeholder(uri: uri, title: title.isEmpty ? self.title(for: uri) : title)
        }
    }

    /// 返回指定 URI 的默认标题。
    static func title(for uri: String) -> String {
        titleMap[uri] ?? uri
    }

    /// 在可用 URI 集合中选取规范形式。
    static func canonicalURI(for uri: String, availableURIs: Set<String>) -> String {
        if availableURIs.contains(uri) {
            return uri
        }
        switch uri {
        case "task_management":
            return availableURIs.contains("task_management_editor") ? "task_management_editor" : uri
        case "task_management_editor":
            return availableURIs.contains("task_management") ? "task_management" : uri
        case "registration_invitation":
            return availableURIs.contains("photographer_invite") ? "photographer_invite" : uri
        case "photographer_invite":
            return availableURIs.contains("registration_invitation") ? "registration_invitation" : uri
        case "pm":
            return availableURIs.contains("pm_manager") ? "pm_manager" : uri
        case "pm_manager":
            return availableURIs.contains("pm") ? "pm" : uri
        case "payment_code":
            return availableURIs.contains("payment_qr") ? "payment_qr" : uri
        default:
            return uri
        }
    }

    /// 返回同义 URI 的去重键。
    static func menuAliasKey(for uri: String) -> String {
        switch uri {
        case "task_management", "task_management_editor":
            return "task_management"
        case "registration_invitation", "photographer_invite":
            return "registration_invitation"
        case "pm", "pm_manager", "project_edit":
            return "pm"
        case "payment_collection", "payment_qr", "payment_code":
            return "payment_collection"
        case "deposit_order_detail", "deposit_order", "deposit_order_shooting_info":
            return "deposit_order"
        case "photographer_orders", "/scenic-order-manage":
            return "photographer_orders"
        case "/scenic-queue", "queue_management":
            return "queue_management"
        default:
            return uri
        }
    }

    /// 返回首页展示标题，部分同义入口统一文案。
    static func displayTitle(for uri: String, fallback: String) -> String {
        switch uri {
        case "registration_invitation", "photographer_invite":
            return "注册邀请"
        case "location_report":
            return "位置上报"
        case "pm", "pm_manager":
            return "项目管理"
        case "space_settings":
            return "空间设置"
        case "task_management", "task_management_editor":
            return "任务管理"
        default:
            return fallback
        }
    }
}

/// 首页权限路由审计器，用于识别权限里哪些 URI 尚未映射。
enum HomePermissionRouteAuditor {
    /// 扫描当前角色权限并分类统计可路由、已知不支持和未知 URI。
    static func audit(permissions: [RolePermissionResponse], currentRoleId: Int?) -> HomePermissionRouteAudit {
        let source: RolePermissionResponse?
        if let currentRoleId {
            source = permissions.first { $0.role.id == currentRoleId }
        } else {
            source = permissions.first
        }

        let entries = uniquePermissionItems(from: source?.role.permission ?? []).map { item in
            let title = item.name.isEmpty ? HomeMenuRouter.title(for: item.uri) : item.name
            return HomePermissionRouteAuditEntry(
                uri: item.uri,
                title: title,
                route: HomeMenuRouter.resolve(uri: item.uri, title: title)
            )
        }

        return HomePermissionRouteAudit(
            routable: entries.filter { entry in
                switch entry.route {
                case .tab, .orders, .destination:
                    return true
                case .unsupported, .placeholder:
                    return false
                }
            },
            unsupported: entries.filter { entry in
                if case .unsupported = entry.route { return true }
                return false
            },
            unknown: entries.filter { entry in
                if case .placeholder = entry.route { return true }
                return false
            }
        )
    }

    /// 生成 Markdown 审计报告。
    static func markdownReport(audit: HomePermissionRouteAudit, generatedAt: Date = Date()) -> String {
        var lines = [
            "# Home Permission Route Audit",
            "",
            "Generated: \(reportDateFormatter.string(from: generatedAt))",
            "",
            "Routable: \(audit.routable.count)",
            "Unsupported: \(audit.unsupported.count)",
            "Unknown: \(audit.unknown.count)",
            ""
        ]

        if audit.unknown.isEmpty {
            lines.append("No unknown permission routes.")
        } else {
            lines.append("## Unknown Routes")
            lines.append("")
            lines.append("| URI | Title |")
            lines.append("| --- | --- |")
            lines.append(contentsOf: audit.unknown.map { "| \(escape($0.uri)) | \(escape($0.title)) |" })
            lines.append("")
            lines.append("Action: map these URIs in `HomeMenuRouter`, confirm unsupported scope, or remove them before release.")
        }

        if !audit.unsupported.isEmpty {
            lines.append("")
            lines.append("## Known Unsupported Routes")
            lines.append("")
            lines.append("| URI | Title | Reason |")
            lines.append("| --- | --- | --- |")
            lines.append(contentsOf: audit.unsupported.map { entry in
                let reason: String
                if case let .unsupported(_, _, value) = entry.route {
                    reason = value
                } else {
                    reason = ""
                }
                return "| \(escape(entry.uri)) | \(escape(entry.title)) | \(escape(reason)) |"
            })
        }

        return lines.joined(separator: "\n")
    }

    private static var reportDateFormatter: ISO8601DateFormatter {
        let formatter = ISO8601DateFormatter()
        formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
        return formatter
    }

    /// 从权限树提取非空 URI，并按同义 URI 去重。
    private static func uniquePermissionItems(from items: [PermissionItem]) -> [PermissionItem] {
        var seen = Set<String>()
        return flatten(items).filter { item in
            guard !item.uri.isEmpty else { return false }
            return seen.insert(HomeMenuRouter.menuAliasKey(for: item.uri)).inserted
        }
    }

    /// 递归展开权限树。
    private static func flatten(_ items: [PermissionItem]) -> [PermissionItem] {
        items.flatMap { item in
            [item] + flatten(item.children)
        }
    }

    /// 转义 Markdown 表格中的特殊字符。
    private static func escape(_ value: String) -> String {
        value
            .replacingOccurrences(of: "\\", with: "\\\\")
            .replacingOccurrences(of: "|", with: "\\|")
            .replacingOccurrences(of: "\n", with: " ")
    }
}

/// 首页未知路由诊断工具，记录运行时无法识别的权限 URI。
enum HomeRouteDiagnostics {
    private static let logger = Logger(subsystem: "com.yuanzhixiang.suixinkan", category: "HomeRouting")
    private static let defaultsKey = "home.routing.unknown.records"
    private static let dateFormatter: ISO8601DateFormatter = {
        let formatter = ISO8601DateFormatter()
        formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
        return formatter
    }()

    /// 记录一个未知首页 URI。
    static func recordUnknown(uri: String, title: String) {
        logger.warning("Unknown home menu uri: \(uri, privacy: .public), title: \(title, privacy: .public)")
        var records = unknownRoutes()
        let now = Date()
        if let index = records.firstIndex(where: { $0.uri == uri }) {
            let current = records[index]
            records[index] = UnknownHomeRouteRecord(
                uri: current.uri,
                title: title.isEmpty ? current.title : title,
                firstSeenAt: current.firstSeenAt,
                lastSeenAt: now,
                count: current.count + 1
            )
        } else {
            records.append(UnknownHomeRouteRecord(uri: uri, title: title, firstSeenAt: now, lastSeenAt: now, count: 1))
        }
        save(records)
    }

    /// 读取所有未知首页路由记录。
    static func unknownRoutes() -> [UnknownHomeRouteRecord] {
        guard let data = UserDefaults.standard.data(forKey: defaultsKey),
              let records = try? JSONDecoder().decode([UnknownHomeRouteRecord].self, from: data)
        else { return [] }
        return records
    }

    /// 生成未知首页路由 Markdown 报告。
    static func unknownRouteReport(generatedAt: Date = Date()) -> String {
        let records = unknownRoutes().sorted { lhs, rhs in
            if lhs.count != rhs.count {
                return lhs.count > rhs.count
            }
            return lhs.lastSeenAt > rhs.lastSeenAt
        }
        var lines = [
            "# Home Route Diagnostics",
            "",
            "Generated: \(dateFormatter.string(from: generatedAt))",
            ""
        ]

        guard !records.isEmpty else {
            lines.append("No unknown home routes recorded.")
            return lines.joined(separator: "\n")
        }

        lines.append("| URI | Title | Count | First Seen | Last Seen |")
        lines.append("| --- | --- | ---: | --- | --- |")
        lines.append(contentsOf: records.map { record in
            "| \(escape(record.uri)) | \(escape(record.title)) | \(record.count) | \(dateFormatter.string(from: record.firstSeenAt)) | \(dateFormatter.string(from: record.lastSeenAt)) |"
        })
        lines.append("")
        lines.append("Action: each URI above must be mapped in `HomeMenuRouter`, confirmed as unsupported scope, or explicitly accepted before release.")
        return lines.joined(separator: "\n")
    }

    /// 清空未知首页路由记录。
    static func resetUnknownRoutes() {
        UserDefaults.standard.removeObject(forKey: defaultsKey)
    }

    /// 保存未知首页路由记录。
    private static func save(_ records: [UnknownHomeRouteRecord]) {
        guard let data = try? JSONEncoder().encode(records) else { return }
        UserDefaults.standard.set(data, forKey: defaultsKey)
    }

    /// 转义 Markdown 表格中的特殊字符。
    private static func escape(_ value: String) -> String {
        value
            .replacingOccurrences(of: "\\", with: "\\\\")
            .replacingOccurrences(of: "|", with: "\\|")
            .replacingOccurrences(of: "\n", with: " ")
    }
}
