//
//  OperatingAreaViews.swift
//  suixinkan
//
//  Created by Codex on 2026/6/25.
//

import CoreLocation
import SwiftUI

#if AMAP_ENABLED
import MAMapKit
#endif

/// 运营区域首页，按当前角色展示店铺或景区运营围栏。
struct OperatingAreaView: View {
    @EnvironmentObject private var accountContext: AccountContext
    @EnvironmentObject private var permissionContext: PermissionContext
    @Environment(\.operatingAreaAPI) private var operatingAreaAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @Environment(\.globalLoading) private var globalLoading

    @StateObject private var viewModel = OperatingAreaViewModel()

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.medium) {
                summarySection
                mapSection
                areaListSection
            }
            .padding(AppMetrics.Spacing.pageHorizontal)
            .padding(.vertical, AppMetrics.Spacing.medium)
        }
        .background(Color(hex: 0xF5F7FA))
        .navigationTitle("运营区域")
        .navigationBarTitleDisplayMode(.inline)
        .refreshable { await reload(showLoading: false) }
        .task(id: taskID) {
            await reload(showLoading: viewModel.items.isEmpty)
        }
    }

    private var taskID: String {
        "\(permissionContext.currentRole?.id ?? 0)-\(accountContext.currentScenic?.id ?? 0)-\(accountContext.currentStore?.id ?? 0)"
    }

    private var summarySection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.medium) {
            HStack {
                VStack(alignment: .leading, spacing: 4) {
                    Text(viewModel.title)
                        .font(.system(size: AppMetrics.FontSize.title3, weight: .semibold))
                        .foregroundStyle(AppDesign.textPrimary)
                    Text(scopeText)
                        .font(.system(size: AppMetrics.FontSize.caption))
                        .foregroundStyle(AppDesign.textSecondary)
                }
                Spacer()
                Image(systemName: "map.fill")
                    .font(.system(size: 22, weight: .semibold))
                    .foregroundStyle(AppDesign.primary)
                    .frame(width: 42, height: 42)
                    .background(AppDesign.primarySoft, in: RoundedRectangle(cornerRadius: 8))
            }

            HStack(spacing: AppMetrics.Spacing.small) {
                OperatingAreaSummaryCard(title: "区域记录", value: "\(viewModel.summary.areaCount)", tint: AppDesign.primary)
                OperatingAreaSummaryCard(title: "有效围栏", value: "\(viewModel.summary.fenceCount)", tint: AppDesign.success)
                OperatingAreaSummaryCard(title: "当前门店", value: "\(viewModel.summary.currentStoreFenceCount)", tint: AppDesign.warning)
            }
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: 8))
    }

    private var mapSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
            HStack {
                Text("围栏地图")
                    .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                    .foregroundStyle(AppDesign.textPrimary)
                Spacer()
                Text(mapLegendText)
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            }

            if let reason = viewModel.blockReason {
                AppContentUnavailableView(reason.message, systemImage: "mappin.slash")
                    .frame(maxWidth: .infinity, minHeight: 260)
                    .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 8))
                    .overlay(alignment: .bottom) {
                        if shouldShowRetry(for: reason) {
                            Button("重新加载") {
                                Task { await reload(showLoading: true) }
                            }
                            .buttonStyle(.borderedProminent)
                            .padding(.bottom, AppMetrics.Spacing.medium)
                        }
                    }
            } else {
                OperatingAreaMapView(rings: viewModel.fenceRings)
                    .frame(height: 320)
                    .clipShape(RoundedRectangle(cornerRadius: 8))
            }
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: 8))
    }

    private var areaListSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
            Text("区域列表")
                .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                .foregroundStyle(AppDesign.textPrimary)

            if viewModel.items.isEmpty {
                Text(viewModel.blockReason?.message ?? "暂无运营区域")
                    .font(.system(size: AppMetrics.FontSize.subheadline))
                    .foregroundStyle(AppDesign.textSecondary)
                    .frame(maxWidth: .infinity, minHeight: 88)
                    .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 8))
            } else {
                ForEach(viewModel.items) { item in
                    let ringCount = viewModel.fenceRings.filter { $0.itemId == item.id }.count
                    OperatingAreaItemRow(item: item, ringCount: ringCount, isCurrentStore: isCurrentStore(item))
                }
            }
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: 8))
    }

    private var scopeText: String {
        switch viewModel.mode {
        case .storeAdmin:
            return accountContext.currentStore?.name ?? "当前店铺"
        case .scenicAdmin:
            return accountContext.currentScenic?.name ?? "当前景区"
        case nil:
            return accountContext.currentScenic?.name ?? accountContext.currentStore?.name ?? "未选择业务范围"
        }
    }

    private var mapLegendText: String {
        switch viewModel.mode {
        case .storeAdmin:
            "红色为当前门店"
        case .scenicAdmin:
            "景区全部围栏"
        case nil:
            "只读展示"
        }
    }

    private func reload(showLoading: Bool) async {
        await globalLoading.withOptionalLoading(showLoading) {
            await viewModel.reload(api: operatingAreaAPI, accountContext: accountContext, permissionContext: permissionContext)
        }
        if let message = viewModel.errorMessage {
            toastCenter.show(message)
        }
    }

    private func isCurrentStore(_ item: OperatingAreaItem) -> Bool {
        guard case .storeAdmin(let storeId)? = viewModel.mode else { return false }
        return item.id == storeId
    }

    private func shouldShowRetry(for reason: OperatingAreaBlockReason) -> Bool {
        if case .backendMessage = reason {
            return true
        }
        return false
    }
}

private struct OperatingAreaSummaryCard: View {
    let title: String
    let value: String
    let tint: Color

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.textSecondary)
            Text(value)
                .font(.system(size: AppMetrics.FontSize.title3, weight: .bold))
                .foregroundStyle(tint)
                .lineLimit(1)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(AppMetrics.Spacing.small)
        .background(tint.opacity(0.1), in: RoundedRectangle(cornerRadius: 8))
    }
}

private struct OperatingAreaItemRow: View {
    let item: OperatingAreaItem
    let ringCount: Int
    let isCurrentStore: Bool

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack(alignment: .top) {
                VStack(alignment: .leading, spacing: 4) {
                    Text(item.name.isEmpty ? "未命名区域" : item.name)
                        .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                        .foregroundStyle(AppDesign.textPrimary)
                    Text("有效围栏 \(ringCount) 个")
                        .font(.system(size: AppMetrics.FontSize.caption))
                        .foregroundStyle(AppDesign.textSecondary)
                }
                Spacer()
                if isCurrentStore {
                    Text("当前门店")
                        .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                        .foregroundStyle(Color(hex: 0xDC2626))
                        .padding(.horizontal, 8)
                        .frame(height: 24)
                        .background(Color(hex: 0xDC2626).opacity(0.12), in: Capsule())
                }
            }
            HStack(spacing: 8) {
                if !item.statusText.isEmpty {
                    OperatingAreaTag(text: item.statusText, color: AppDesign.success)
                }
                if !item.typeText.isEmpty {
                    OperatingAreaTag(text: item.typeText, color: AppDesign.primary)
                }
                if !item.auditStatusText.isEmpty {
                    OperatingAreaTag(text: item.auditStatusText, color: AppDesign.warning)
                }
            }
        }
        .padding(AppMetrics.Spacing.small)
        .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 8))
    }
}

private struct OperatingAreaTag: View {
    let text: String
    let color: Color

    var body: some View {
        Text(text)
            .font(.system(size: AppMetrics.FontSize.caption))
            .foregroundStyle(color)
            .padding(.horizontal, 8)
            .frame(height: 22)
            .background(color.opacity(0.12), in: Capsule())
    }
}

private struct OperatingAreaMapView: View {
    let rings: [OperatingFenceRing]

    var body: some View {
        #if AMAP_ENABLED
        OperatingAreaAMapRepresentable(rings: rings)
        #else
        OperatingAreaMapFallback(rings: rings)
        #endif
    }
}

private struct OperatingAreaMapFallback: View {
    let rings: [OperatingFenceRing]

    var body: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
            Label("模拟器未启用高德地图，以下为围栏坐标摘要", systemImage: "map")
                .font(.system(size: AppMetrics.FontSize.subheadline, weight: .medium))
                .foregroundStyle(AppDesign.textSecondary)
            ScrollView {
                LazyVStack(alignment: .leading, spacing: 8) {
                    ForEach(rings) { ring in
                        VStack(alignment: .leading, spacing: 4) {
                            Text(ring.regionName.isEmpty ? "未命名区域" : ring.regionName)
                                .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                                .foregroundStyle(ring.isCurrentStore ? Color(hex: 0xDC2626) : AppDesign.textPrimary)
                            Text(ring.points.prefix(4).map { String(format: "%.6f, %.6f", $0.latitude, $0.longitude) }.joined(separator: "  "))
                                .font(.system(size: AppMetrics.FontSize.caption))
                                .foregroundStyle(AppDesign.textSecondary)
                                .lineLimit(2)
                        }
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding(10)
                        .background(.white, in: RoundedRectangle(cornerRadius: 8))
                    }
                }
            }
        }
        .padding(AppMetrics.Spacing.medium)
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
        .background(Color(hex: 0xEEF2F7))
    }
}

#if AMAP_ENABLED
private struct OperatingAreaAMapRepresentable: UIViewRepresentable {
    let rings: [OperatingFenceRing]

    func makeCoordinator() -> Coordinator {
        Coordinator()
    }

    func makeUIView(context: Context) -> MAMapView {
        let mapView = MAMapView(frame: .zero)
        mapView.delegate = context.coordinator
        mapView.showsCompass = false
        mapView.showsScale = false
        mapView.isRotateEnabled = false
        return mapView
    }

    func updateUIView(_ mapView: MAMapView, context: Context) {
        context.coordinator.ringsByOverlay.removeAll()
        mapView.removeOverlays(mapView.overlays)
        mapView.removeAnnotations(mapView.annotations)

        var allCoordinates: [CLLocationCoordinate2D] = []
        for ring in rings {
            var coordinates = ring.points.map {
                CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude)
            }
            guard coordinates.count >= 3 else { continue }
            guard let polygon = MAPolygon(coordinates: &coordinates, count: UInt(coordinates.count)) else {
                continue
            }
            context.coordinator.ringsByOverlay[ObjectIdentifier(polygon)] = ring
            mapView.add(polygon)
            allCoordinates.append(contentsOf: coordinates)

            if let center = ring.centerCoordinate {
                let annotation = MAPointAnnotation()
                annotation.coordinate = center
                annotation.title = ring.regionName
                mapView.addAnnotation(annotation)
            }
        }

        if let region = Self.region(for: allCoordinates) {
            mapView.setRegion(region, animated: true)
        }
    }

    static func dismantleUIView(_ uiView: MAMapView, coordinator: Coordinator) {
        uiView.delegate = nil
    }

    private static func region(for coordinates: [CLLocationCoordinate2D]) -> MACoordinateRegion? {
        guard !coordinates.isEmpty else { return nil }
        let minLat = coordinates.map(\.latitude).min() ?? 0
        let maxLat = coordinates.map(\.latitude).max() ?? 0
        let minLng = coordinates.map(\.longitude).min() ?? 0
        let maxLng = coordinates.map(\.longitude).max() ?? 0
        let center = CLLocationCoordinate2D(latitude: (minLat + maxLat) / 2, longitude: (minLng + maxLng) / 2)
        let span = MACoordinateSpan(
            latitudeDelta: max((maxLat - minLat) * 1.4, 0.01),
            longitudeDelta: max((maxLng - minLng) * 1.4, 0.01)
        )
        return MACoordinateRegion(center: center, span: span)
    }

    final class Coordinator: NSObject, MAMapViewDelegate {
        var ringsByOverlay: [ObjectIdentifier: OperatingFenceRing] = [:]

        func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
            guard let polygon = overlay as? MAPolygon else { return nil }
            let ring = ringsByOverlay[ObjectIdentifier(polygon)]
            let renderer = MAPolygonRenderer(polygon: polygon)
            let color = ring?.isCurrentStore == true ? UIColor.systemRed : UIColor.systemBlue
            renderer?.strokeColor = color
            renderer?.fillColor = color.withAlphaComponent(0.18)
            renderer?.lineWidth = 3
            return renderer
        }
    }
}

private extension OperatingFenceRing {
    var centerCoordinate: CLLocationCoordinate2D? {
        guard !points.isEmpty else { return nil }
        let latitude = points.reduce(0) { $0 + $1.latitude } / Double(points.count)
        let longitude = points.reduce(0) { $0 + $1.longitude } / Double(points.count)
        return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}
#endif
