//
//  WildPhotographerReportAPI.swift
//  suixinkan
//

import Foundation

/// 举报摄影师服务协议，封装举报类型等后端接口。
@MainActor
protocol WildPhotographerReportServing {
    /// 拉取提交举报可选类型。
    func reportTypes() async throws -> WildReportTypeListResponse
    /// 拉取举报首页须知与规则文案。
    func reportCopy() async throws -> WildReportCopyResponse
    /// 提交摄影师举报。
    func submitReport(_ request: WildReportSubmitRequest) async throws -> WildReportSubmitResponse
    /// 为已有举报补充证据。
    func supplementReport(_ request: WildReportSupplementRequest) async throws
    /// 拉取附近风险地图点位。
    func riskMap(_ request: WildReportRiskMapRequest) async throws -> WildReportRiskMapResponse
    /// 拉取风险地图单个标记详情。
    func markerDetail(_ request: WildReportMarkerDetailRequest) async throws -> WildReportMarkerDetailResponse
    /// 拉取我的举报列表。
    func reportList(_ request: WildReportListRequest) async throws -> WildReportListResponse
    /// 拉取单条举报详情。
    func reportDetail(id: Int) async throws -> WildReportDetailData
    /// 拉取举报微信小程序分享配置。
    func reportShare(id: String) async throws -> WildReportMiniProgramShareData
}

/// 举报摄影师 API，负责和 `photog/report` 相关接口通讯。
@MainActor
final class WildPhotographerReportAPI: WildPhotographerReportServing {
    private let client: APIClient

    /// 初始化举报摄影师 API。
    init(client: APIClient) {
        self.client = client
    }

    /// 拉取提交举报可选类型。
    func reportTypes() async throws -> WildReportTypeListResponse {
        try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/report/types")
        )
    }

    /// 拉取举报首页须知与规则文案。
    func reportCopy() async throws -> WildReportCopyResponse {
        try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/report/copy")
        )
    }

    /// 提交摄影师举报。
    func submitReport(_ request: WildReportSubmitRequest) async throws -> WildReportSubmitResponse {
        try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/report/submit",
                body: request
            )
        )
    }

    /// 为已有举报补充证据。
    func supplementReport(_ request: WildReportSupplementRequest) async throws {
        let _: EmptyPayload = try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/report/supplement",
                body: request
            )
        )
    }

    /// 拉取附近风险地图点位。
    func riskMap(_ request: WildReportRiskMapRequest) async throws -> WildReportRiskMapResponse {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/report/risk-map",
                queryItems: request.queryItems
            )
        )
    }

    /// 拉取风险地图单个标记详情。
    func markerDetail(_ request: WildReportMarkerDetailRequest) async throws -> WildReportMarkerDetailResponse {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/report/marker-detail",
                queryItems: request.queryItems
            )
        )
    }

    /// 拉取我的举报列表。
    func reportList(_ request: WildReportListRequest) async throws -> WildReportListResponse {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/report/list",
                queryItems: request.queryItems
            )
        )
    }

    /// 拉取单条举报详情。
    func reportDetail(id: Int) async throws -> WildReportDetailData {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/report/detail",
                queryItems: [URLQueryItem(name: "id", value: String(id))]
            )
        )
    }

    /// 拉取举报微信小程序分享配置。
    func reportShare(id: String) async throws -> WildReportMiniProgramShareData {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/report/share",
                queryItems: [URLQueryItem(name: "id", value: id)]
            )
        )
    }
}

/// 补充证据接口请求体。
struct WildReportSupplementRequest: Encodable, Equatable {
    let id: Int
    let desc: String?
    let evidences: [WildReportEvidenceRequest]?
}

/// 附近风险地图接口请求参数。
struct WildReportRiskMapRequest: Encodable, Equatable {
    let scenicId: Int
    let latitude: Double?
    let longitude: Double?

    var queryItems: [URLQueryItem] {
        var items = [URLQueryItem(name: "scenic_id", value: String(scenicId))]
        if let latitude {
            items.append(URLQueryItem(name: "latitude", value: String(latitude)))
        }
        if let longitude {
            items.append(URLQueryItem(name: "longitude", value: String(longitude)))
        }
        return items
    }

    enum CodingKeys: String, CodingKey {
        case scenicId = "scenic_id"
        case latitude
        case longitude
    }
}

/// 风险地图标记详情接口请求参数。
struct WildReportMarkerDetailRequest: Encodable, Equatable {
    let scenicId: Int
    let markerType: String
    let id: Int
    let latitude: Double?
    let longitude: Double?

    var queryItems: [URLQueryItem] {
        var items = [
            URLQueryItem(name: "scenic_id", value: String(scenicId)),
            URLQueryItem(name: "marker_type", value: markerType),
            URLQueryItem(name: "id", value: String(id))
        ]
        if let latitude {
            items.append(URLQueryItem(name: "latitude", value: String(latitude)))
        }
        if let longitude {
            items.append(URLQueryItem(name: "longitude", value: String(longitude)))
        }
        return items
    }

    enum CodingKeys: String, CodingKey {
        case scenicId = "scenic_id"
        case markerType = "marker_type"
        case id
        case latitude
        case longitude
    }
}

/// 提交举报接口请求体。
struct WildReportSubmitRequest: Encodable, Equatable {
    let scenicId: Int
    let reportType: Int
    let desc: String
    let storeUserId: Int?
    let contactPhone: String?
    let locationName: String?
    let locationAddress: String?
    let lat: Double
    let lng: Double
    let evidences: [WildReportEvidenceRequest]
    let paymentScreenshots: [WildReportEvidenceRequest]

    enum CodingKeys: String, CodingKey {
        case scenicId = "scenic_id"
        case reportType = "report_type"
        case desc
        case storeUserId = "store_user_id"
        case contactPhone = "contact_phone"
        case locationName = "location_name"
        case locationAddress = "location_address"
        case lat
        case lng
        case evidences
        case paymentScreenshots = "payment_screenshots"
    }
}

/// 提交举报接口响应体，包含后端生成的举报 ID 和举报编号。
struct WildReportSubmitResponse: Decodable, Equatable {
    let id: Int
    let complaintNo: String

    enum CodingKeys: String, CodingKey {
        case id
        case complaintNo = "complaint_no"
    }

    init(id: Int = 0, complaintNo: String = "") {
        self.id = id
        self.complaintNo = complaintNo
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeIfPresent(Int.self, forKey: .id) ?? 0
        complaintNo = try container.decodeIfPresent(String.self, forKey: .complaintNo) ?? ""
    }
}

/// 提交举报接口中的附件项。
struct WildReportEvidenceRequest: Encodable, Equatable {
    let fileURL: String
    let fileType: Int
    let fileName: String?

    enum CodingKeys: String, CodingKey {
        case fileURL = "file_url"
        case fileType = "file_type"
        case fileName = "file_name"
    }
}
