//
//  WildPhotographerReportMapViews
//  suixinkan
//
//  Created by Codex on 2026/7/1.
//

import MapKit
import SwiftUI
import UIKit

struct WildReportRiskMapView: View {
    let record: WildReportRecord
    let riskPoints: [WildReportRiskPoint]

    @StateObject private var viewModel: WildReportRiskMapViewModel
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass

    init(record: WildReportRecord, riskPoints: [WildReportRiskPoint]) {
        self.record = record
        self.riskPoints = riskPoints
        _viewModel = StateObject(wrappedValue: WildReportRiskMapViewModel(record: record, riskPoints: riskPoints))
    }

    var body: some View {
        VStack(spacing: 0) {
            mapSection
            legendBar
            Divider()
            bottomPanel
        }
        .navigationTitle("附近风险地图")
        .navigationBarTitleDisplayMode(.inline)
        .background(Color(hex: 0xF8FAFF).ignoresSafeArea())
        .fullScreenCover(item: $viewModel.previewMedia) { media in
            WildReportMapMediaPreviewView(media: media) {
                viewModel.dismissMediaPreview()
            }
        }
        .fullScreenCover(item: $viewModel.previewImageURL) { item in
            WildReportMapURLImagePreviewView(imageURL: item.url) {
                viewModel.dismissImagePreview()
            }
        }
        .overlay(alignment: .bottom) {
            if let toast = viewModel.toastMessage {
                Text(toast)
                    .font(.system(size: 14, weight: .medium))
                    .foregroundStyle(.white)
                    .padding(.horizontal, 16)
                    .padding(.vertical, 10)
                    .background(Color.black.opacity(0.78), in: Capsule())
                    .padding(.bottom, 24)
                    .transition(.move(edge: .bottom).combined(with: .opacity))
                    .onAppear {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 1.8) {
                            viewModel.clearToast()
                        }
                    }
            }
        }
    }

    private var mapSection: some View {
        ZStack(alignment: .topLeading) {
            Map(
                coordinateRegion: $viewModel.region,
                annotationItems: viewModel.markers
            ) { marker in
                MapAnnotation(coordinate: marker.coordinate) {
                    Button {
                        viewModel.selectMarker(marker)
                    } label: {
                        WildReportMapMarkerView(
                            marker: marker,
                            isSelected: viewModel.selectedMarkerID == marker.id
                        )
                    }
                    .buttonStyle(.plain)
                }
            }

            HStack(spacing: 6) {
                Image(systemName: "mountain.2.fill")
                    .font(.system(size: 13, weight: .semibold))
                Text(viewModel.scenicAreaName)
                    .font(.system(size: 13, weight: .semibold))
            }
            .foregroundStyle(AppDesign.primary)
            .padding(.horizontal, 10)
            .frame(height: 30)
            .background(.white.opacity(0.94), in: Capsule())
            .padding(12)
        }
        .frame(height: horizontalSizeClass == .regular ? 420 : 340)
    }

    private var legendBar: some View {
        HStack(spacing: 0) {
            legendItem(color: AppDesign.primary, title: "我的位置")
            legendItem(color: AppDesign.danger, title: "疑似打野")
            legendItem(color: Color(hex: 0xF59E0B), title: "处理中线索")
            legendItem(color: AppDesign.success, title: "内部摄影师")
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 12)
        .background(.white)
    }

    @ViewBuilder
    private var bottomPanel: some View {
        ScrollView(.vertical, showsIndicators: true) {
            VStack(spacing: 0) {
                if let marker = viewModel.selectedMarker {
                    if case .activeClue(let clue) = marker.detail {
                        WildReportRadarResultCardView(
                            clue: clue,
                            onPreviewImage: { url in
                                viewModel.showImagePreview(url)
                            },
                            onNavigate: {
                                viewModel.navigateToSelectedMarker()
                            },
                            onShare: {
                                viewModel.shareSelectedClue()
                            }
                        )
                    }
                } else {
                    Text("点击地图标记查看详情")
                        .font(.system(size: 14))
                        .foregroundStyle(AppDesign.textSecondary)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 40)
                }
            }
            .frame(maxWidth: .infinity, alignment: .top)
        }
        .frame(minHeight: 0, maxHeight: .infinity)
        .background(Color(hex: 0xF8FAFF))
    }

    private func legendItem(color: Color, title: String) -> some View {
        HStack(spacing: 6) {
            WildReportMapDot(color: color, size: 10)
            Text(title)
                .font(.system(size: 11, weight: .medium))
                .foregroundStyle(AppDesign.textPrimary)
                .lineLimit(1)
                .minimumScaleFactor(0.8)
        }
        .frame(maxWidth: .infinity)
    }
}

private struct WildReportRadarResultCardView: View {
    let clue: WildReportRadarActiveClue
    let onPreviewImage: (String) -> Void
    let onNavigate: () -> Void
    let onShare: () -> Void

    var body: some View {
        VStack(alignment: .leading, spacing: 14) {
            headerSection

            if clue.type == .blue, let nearestAbnormalText = clue.nearestAbnormalText {
                compareText(nearestAbnormalText)
            }

            if clue.type == .green {
                photographerProfile
            }

            if clue.type == .red {
                reporterInfo
            }

            if clue.type == .red, !clue.reportContents.isEmpty {
                reportContentsSection
            }

            if clue.type == .green, let summary = clue.summary {
                compareText(summary)
            }

            if clue.type == .green, let detail = clue.detail {
                detailSection(detail)
            }

            if clue.type == .red, !clue.images.isEmpty {
                imagesSection
            }

            if clue.type == .red, clue.processingStarted, let record = clue.record {
                processingPanel(record: record)
            }

            if clue.completed, let completionPhoto = clue.completionPhoto {
                completionProofSection(completionPhoto)
            }

            if !clue.completed {
                actionButtons
            }
        }
        .padding(16)
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(.white, in: RoundedRectangle(cornerRadius: 16))
        .overlay(
            RoundedRectangle(cornerRadius: 16)
                .stroke(AppDesign.border, lineWidth: 1)
        )
        .padding(16)
    }

    private var headerSection: some View {
        HStack(alignment: .top, spacing: 12) {
            Image(systemName: "location.fill")
                .font(.system(size: 20, weight: .semibold))
                .foregroundStyle(.white)
                .frame(width: 44, height: 44)
                .background(headerIconColor, in: RoundedRectangle(cornerRadius: 12))

            VStack(alignment: .leading, spacing: 6) {
                if clue.type == .red {
                    Text("线索 ID：\(clue.id)")
                        .font(.system(size: 16, weight: .bold))
                        .foregroundStyle(AppDesign.textPrimary)
                    HStack(spacing: 12) {
                        if let distanceText = clue.distanceText {
                            Text("距离：距离您\(distanceText)")
                        }
                        if let updatedAt = clue.updatedAt {
                            Text("时间：\(updatedAt)")
                        }
                    }
                    .font(.system(size: 12))
                    .foregroundStyle(AppDesign.textSecondary)
                } else {
                    Text(clue.displayTitle)
                        .font(.system(size: 16, weight: .bold))
                        .foregroundStyle(AppDesign.textPrimary)
                    if clue.type == .green {
                        HStack(spacing: 12) {
                            if let distance = clue.distance {
                                Text("距蓝点 \(distance)")
                            }
                            if let direction = clue.direction {
                                Text(direction)
                            }
                            if let updatedAt = clue.updatedAt {
                                Text(updatedAt)
                            }
                        }
                        .font(.system(size: 12))
                        .foregroundStyle(AppDesign.textSecondary)
                    }
                }
            }

            Spacer(minLength: 8)

            Text(clue.statusText)
                .font(.system(size: 11, weight: .semibold))
                .foregroundStyle(statusColor)
                .padding(.horizontal, 8)
                .frame(height: 24)
                .background(statusColor.opacity(0.12), in: Capsule())
        }
    }

    private var photographerProfile: some View {
        HStack(spacing: 12) {
            Image(systemName: clue.avatar ?? "person.crop.circle.fill")
                .font(.system(size: 42, weight: .semibold))
                .foregroundStyle(AppDesign.success)
                .frame(width: 56, height: 56)
                .background(AppDesign.success.opacity(0.12), in: Circle())

            VStack(alignment: .leading, spacing: 4) {
                if let name = clue.name {
                    Text(name)
                        .font(.system(size: 16, weight: .bold))
                        .foregroundStyle(AppDesign.textPrimary)
                }
                if let storeName = clue.storeName {
                    Text(storeName)
                        .font(.system(size: 13, weight: .semibold))
                        .foregroundStyle(AppDesign.success)
                }
            }
        }
    }

    private var reporterInfo: some View {
        VStack(spacing: 10) {
            infoLabelRow(label: "举报人", value: clue.reporterName ?? "-")
            HStack {
                Text("举报人手机号")
                    .font(.system(size: 13))
                    .foregroundStyle(AppDesign.textSecondary)
                Spacer()
                if let phone = clue.reporterPhone, let masked = clue.maskedReporterPhone {
                    Button {
                        callPhone(phone)
                    } label: {
                        HStack(spacing: 6) {
                            Text(masked)
                                .font(.system(size: 14, weight: .semibold))
                                .foregroundStyle(AppDesign.primary)
                            Image(systemName: "phone.fill")
                                .font(.system(size: 13, weight: .semibold))
                                .foregroundStyle(AppDesign.primary)
                        }
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .padding(12)
        .background(Color(hex: 0xF9FAFB), in: RoundedRectangle(cornerRadius: 10))
    }

    private var reportContentsSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            ForEach(Array(clue.reportContents.enumerated()), id: \.offset) { _, item in
                VStack(alignment: .leading, spacing: 4) {
                    Text(item.time)
                        .font(.system(size: 11, weight: .semibold))
                        .foregroundStyle(AppDesign.textSecondary)
                    Text(item.content)
                        .font(.system(size: 13))
                        .foregroundStyle(AppDesign.textPrimary)
                        .lineSpacing(4)
                }
            }
        }
    }

    private var imagesSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text("现场图片/视频")
                .font(.system(size: 15, weight: .bold))
                .foregroundStyle(AppDesign.textPrimary)

            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 10) {
                    ForEach(clue.images, id: \.self) { url in
                        Button {
                            onPreviewImage(url)
                        } label: {
                            AsyncImage(url: URL(string: url)) { phase in
                                switch phase {
                                case .success(let image):
                                    image
                                        .resizable()
                                        .scaledToFill()
                                default:
                                    RoundedRectangle(cornerRadius: 10)
                                        .fill(Color(hex: 0xE5E7EB))
                                        .overlay {
                                            ProgressView()
                                        }
                                }
                            }
                            .frame(width: 108, height: 108)
                            .clipShape(RoundedRectangle(cornerRadius: 10))
                        }
                        .buttonStyle(.plain)
                    }
                }
            }
        }
    }

    private func processingPanel(record: WildReportRadarProcessRecord) -> some View {
        VStack(spacing: 10) {
            infoLabelRow(label: "处理人", value: record.handlerName)
            infoLabelRow(
                label: "状态",
                value: clue.completed ? "已处理" : "正在处理中",
                valueColor: clue.completed ? AppDesign.success : Color(hex: 0xF59E0B)
            )
            HStack {
                Text("联系电话")
                    .font(.system(size: 13))
                    .foregroundStyle(AppDesign.textSecondary)
                Spacer()
                Button {
                    callPhone(record.phone)
                } label: {
                    HStack(spacing: 6) {
                        Text(record.maskedPhone)
                            .font(.system(size: 14, weight: .semibold))
                            .foregroundStyle(AppDesign.primary)
                        Image(systemName: "phone.fill")
                            .font(.system(size: 13, weight: .semibold))
                            .foregroundStyle(AppDesign.primary)
                    }
                }
                .buttonStyle(.plain)
            }

            VStack(alignment: .leading, spacing: 10) {
                Text("处理进度")
                    .font(.system(size: 14, weight: .bold))
                    .foregroundStyle(AppDesign.textPrimary)

                ForEach(Array(clue.processingTimeline.enumerated()), id: \.offset) { _, item in
                    HStack(alignment: .top, spacing: 10) {
                        Circle()
                            .fill(timelineDotColor(item.status))
                            .frame(width: 10, height: 10)
                            .padding(.top, 4)
                        VStack(alignment: .leading, spacing: 2) {
                            Text(item.title)
                                .font(.system(size: 13, weight: .semibold))
                                .foregroundStyle(AppDesign.textPrimary)
                            Text(item.time)
                                .font(.system(size: 12))
                                .foregroundStyle(AppDesign.textSecondary)
                        }
                    }
                }
            }
            .padding(.top, 4)
        }
        .padding(12)
        .background(Color(hex: 0xFFFBEB), in: RoundedRectangle(cornerRadius: 10))
    }

    private func completionProofSection(_ photoURL: String) -> some View {
        Button {
            onPreviewImage(photoURL)
        } label: {
            HStack(spacing: 12) {
                AsyncImage(url: URL(string: photoURL)) { phase in
                    switch phase {
                    case .success(let image):
                        image
                            .resizable()
                            .scaledToFill()
                    default:
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color(hex: 0xE5E7EB))
                    }
                }
                .frame(width: 72, height: 72)
                .clipShape(RoundedRectangle(cornerRadius: 10))

                VStack(alignment: .leading, spacing: 4) {
                    Text("处理照片已上传")
                        .font(.system(size: 14, weight: .bold))
                        .foregroundStyle(AppDesign.textPrimary)
                    Text("点击可查看本次处理凭证")
                        .font(.system(size: 12))
                        .foregroundStyle(AppDesign.textSecondary)
                }
                Spacer()
            }
        }
        .buttonStyle(.plain)
    }

    private var actionButtons: some View {
        HStack(spacing: 10) {
            Button(action: onNavigate) {
                HStack(spacing: 6) {
                    Image(systemName: "map.fill")
                    Text(clue.actionText)
                }
                .font(.system(size: 15, weight: .bold))
                .foregroundStyle(.white)
                .frame(maxWidth: .infinity)
                .frame(height: 44)
                .background(AppDesign.primary, in: RoundedRectangle(cornerRadius: 12))
            }
            .buttonStyle(.plain)

            if clue.type == .red, !clue.completed {
                Button(action: onShare) {
                    HStack(spacing: 6) {
                        Image(systemName: "square.and.arrow.up")
                        Text("分享")
                    }
                    .font(.system(size: 15, weight: .bold))
                    .foregroundStyle(.white)
                    .frame(maxWidth: .infinity)
                    .frame(height: 44)
                    .background(AppDesign.success, in: RoundedRectangle(cornerRadius: 12))
                }
                .buttonStyle(.plain)
            }
        }
    }

    private func compareText(_ text: String) -> some View {
        Text(text)
            .font(.system(size: 13))
            .foregroundStyle(AppDesign.textSecondary)
            .lineSpacing(4)
            .padding(12)
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(Color(hex: 0xF3F4F6), in: RoundedRectangle(cornerRadius: 10))
    }

    private func detailSection(_ detail: String) -> some View {
        HStack(alignment: .top, spacing: 8) {
            Image(systemName: "doc.text.fill")
                .font(.system(size: 16, weight: .semibold))
                .foregroundStyle(AppDesign.primary)
                .padding(.top, 2)
            Text(detail)
                .font(.system(size: 13))
                .foregroundStyle(AppDesign.textPrimary)
                .lineSpacing(4)
        }
    }

    private func infoLabelRow(label: String, value: String, valueColor: Color = AppDesign.textPrimary) -> some View {
        HStack {
            Text(label)
                .font(.system(size: 13))
                .foregroundStyle(AppDesign.textSecondary)
            Spacer()
            Text(value)
                .font(.system(size: 14, weight: .semibold))
                .foregroundStyle(valueColor)
        }
    }

    private var headerIconColor: Color {
        if clue.type == .red, clue.processingStarted, !clue.completed {
            return Color(hex: 0xF59E0B)
        }
        switch clue.type {
        case .blue: return AppDesign.primary
        case .green: return AppDesign.success
        case .red: return AppDesign.danger
        }
    }

    private var statusColor: Color {
        if clue.completed { return AppDesign.success }
        if clue.processingStarted && !clue.completed { return Color(hex: 0xF59E0B) }
        switch clue.type {
        case .blue: return AppDesign.primary
        case .green: return AppDesign.success
        case .red: return AppDesign.danger
        }
    }

    private func timelineDotColor(_ status: String) -> Color {
        switch status {
        case "done": return AppDesign.success
        case "current": return Color(hex: 0xF59E0B)
        default: return Color(hex: 0xD1D5DB)
        }
    }

    private func callPhone(_ phone: String) {
        guard let url = URL(string: "tel://\(phone)") else { return }
        UIApplication.shared.open(url)
    }
}

struct WildReportMapURLImagePreviewView: View {
    let imageURL: String
    let onClose: () -> Void

    var body: some View {
        ZStack {
            Color.black.ignoresSafeArea()

            VStack(spacing: 18) {
                Spacer()

                AsyncImage(url: URL(string: imageURL)) { phase in
                    switch phase {
                    case .success(let image):
                        image
                            .resizable()
                            .scaledToFit()
                            .frame(maxWidth: 320, maxHeight: 320)
                            .clipShape(RoundedRectangle(cornerRadius: 18))
                    default:
                        ProgressView()
                            .tint(.white)
                    }
                }

                Text("演示环境图片预览")
                    .font(.system(size: 13))
                    .foregroundStyle(.white.opacity(0.72))

                Spacer()

                Button(action: onClose) {
                    Text("关闭")
                        .font(.system(size: 17, weight: .bold))
                        .foregroundStyle(.white)
                        .frame(width: 132, height: 44)
                        .background(.white.opacity(0.18), in: Capsule())
                }
                .buttonStyle(.plain)
                .padding(.bottom, 36)
            }
        }
    }
}

private struct WildReportMapMediaPreviewView: View {
    let media: WildReportMapMediaItem
    let onClose: () -> Void

    var body: some View {
        ZStack {
            Color.black.ignoresSafeArea()

            VStack(spacing: 18) {
                Spacer()

                ZStack {
                    RoundedRectangle(cornerRadius: 18)
                        .fill(
                            LinearGradient(
                                colors: [media.tint.opacity(0.45), media.tint.opacity(0.18)],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                        )
                        .frame(width: 280, height: 280)

                    Image(systemName: media.systemImage)
                        .font(.system(size: 72, weight: .semibold))
                        .foregroundStyle(.white)

                    if media.isVideo {
                        Image(systemName: "play.circle.fill")
                            .font(.system(size: 56, weight: .semibold))
                            .foregroundStyle(.white.opacity(0.92))
                    }
                }

                Text(media.title)
                    .font(.system(size: 16, weight: .semibold))
                    .foregroundStyle(.white)

                Text(media.isVideo ? "演示环境视频预览" : "演示环境图片预览")
                    .font(.system(size: 13))
                    .foregroundStyle(.white.opacity(0.72))

                Spacer()

                Button(action: onClose) {
                    Text("关闭")
                        .font(.system(size: 17, weight: .bold))
                        .foregroundStyle(.white)
                        .frame(width: 132, height: 44)
                        .background(.white.opacity(0.18), in: Capsule())
                }
                .buttonStyle(.plain)
                .padding(.bottom, 36)
            }
        }
    }
}

private struct WildReportMapMarkerView: View {
    let marker: WildReportMapMarker
    let isSelected: Bool

    private let dotSize: CGFloat = 14

    var body: some View {
        VStack(spacing: 4) {
            if marker.kind == .selfLocation {
                Text(marker.title)
                    .font(.system(size: 11, weight: .semibold))
                    .foregroundStyle(AppDesign.textPrimary)
                    .padding(.horizontal, 8)
                    .padding(.vertical, 4)
                    .background(.white, in: Capsule())
                    .shadow(color: .black.opacity(0.08), radius: 4, y: 2)
            }

            ZStack {
                WildReportMapPulseRings(color: markerColor)

                if isSelected {
                    Circle()
                        .stroke(markerColor.opacity(0.45), lineWidth: 2)
                        .frame(width: 28, height: 28)
                }

                Circle()
                    .fill(markerColor)
                    .frame(width: dotSize, height: dotSize)
                    .overlay(
                        Circle()
                            .stroke(.white, lineWidth: 2)
                    )
            }
            .frame(width: 56, height: 56)
        }
        .padding(4)
    }

    private var markerColor: Color {
        switch marker.kind {
        case .selfLocation: return AppDesign.primary
        case .wildPhotographer: return AppDesign.danger
        case .processingClue: return Color(hex: 0xF59E0B)
        case .peerPhotographer: return AppDesign.success
        }
    }
}

private struct WildReportMapPulseRings: View {
    let color: Color

    @State private var animatePulse = false

    var body: some View {
        ZStack {
            ForEach(0..<3, id: \.self) { index in
                Circle()
                    .stroke(color.opacity(0.32), lineWidth: 2)
                    .frame(
                        width: animatePulse ? dotSize + 14 + CGFloat(index * 12) : dotSize + 6,
                        height: animatePulse ? dotSize + 14 + CGFloat(index * 12) : dotSize + 6
                    )
                    .opacity(animatePulse ? 0 : 0.72)
            }
        }
        .onAppear {
            withAnimation(.easeOut(duration: 2).repeatForever(autoreverses: false)) {
                animatePulse = true
            }
        }
    }

    private let dotSize: CGFloat = 14
}

private struct WildReportMapDot: View {
    let color: Color
    let size: CGFloat

    var body: some View {
        Circle()
            .fill(color)
            .frame(width: size, height: size)
            .overlay(
                Circle()
                    .stroke(.white, lineWidth: 2)
            )
    }
}

#Preview("举报摄影师") {
    NavigationStack {
        WildPhotographerReportHomeView()
    }
}

#Preview("提交举报") {
    NavigationStack {
        WildPhotographerReportSubmitView(homeViewModel: WildPhotographerReportHomeViewModel())
    }
}

#Preview("举报成功") {
    NavigationStack {
        WildPhotographerReportSuccessView(
            result: WildReportSubmitResult(
                record: WildPhotographerReportMockStore.seedReports[0],
                imageCount: 3,
                videoCount: 1
            ),
            homeViewModel: WildPhotographerReportHomeViewModel(),
            onReturnHome: {}
        )
    }
}

#Preview("举报详情") {
    NavigationStack {
        WildPhotographerReportDetailView(
            record: WildPhotographerReportMockStore.seedReports[0],
            homeViewModel: WildPhotographerReportHomeViewModel()
        )
    }
}

#Preview("附近风险地图") {
    NavigationStack {
        WildReportRiskMapView(
            record: WildPhotographerReportMockStore.seedReports[0],
            riskPoints: WildPhotographerReportMockStore.seedRiskPoints
        )
    }
}
