//
//  AssetsAPI.swift
//  suixinkan
//
//  Created by Codex on 2026/6/23.
//

import Foundation
import Combine

/// 资产服务协议，抽象云盘、媒体库和相册接口以便 ViewModel 测试替换。
@MainActor
protocol AssetsServing {
    /// 获取云盘文件列表。
    func cloudFileList(parentFolderId: Int, name: String, type: Int, orderBy: Int, page: Int, pageSize: Int) async throws -> ListPayload<CloudDriveFile>

    /// 创建云盘文件夹。
    func cloudFolderCreate(_ request: CloudFolderCreateRequest) async throws

    /// 登记已上传到 OSS 的云盘文件。
    func cloudFileUpload(_ request: CloudFileUploadRequest) async throws

    /// 删除云盘文件或文件夹。
    func cloudFileDelete(_ request: CloudFileDeleteRequest) async throws

    /// 移动云盘文件或文件夹。
    func cloudFileMove(_ request: CloudFileMoveRequest) async throws

    /// 重命名云盘文件夹。
    func cloudFolderEdit(_ request: CloudFolderModifyRequest) async throws

    /// 重命名云盘文件。
    func cloudFileEdit(_ request: CloudFileModifyRequest) async throws

    /// 检查当前账号是否允许上传云盘文件。
    func checkCloudUploadPermission() async throws -> CheckCloudUploadResponse

    /// 获取素材或样片列表。
    func mediaAlbumList(kind: MediaLibraryKind, keyword: String, status: Int?, page: Int, pageSize: Int) async throws -> MediaLibraryListResponse

    /// 获取素材或样片详情。
    func mediaAlbumDetail(id: Int, kind: MediaLibraryKind) async throws -> MediaLibraryDetail

    /// 更新素材或样片上下架状态。
    func mediaAlbumOperation(_ request: MediaAlbumOperationRequest) async throws

    /// 删除素材或样片。
    func mediaAlbumDelete(_ request: MediaAlbumDeleteRequest) async throws

    /// 新增素材标签。
    func mediaAlbumAddTag(_ request: MediaAlbumAddTagRequest) async throws

    /// 上传素材或样片。
    func mediaAlbumUpload(_ request: MediaAlbumUploadRequest) async throws

    /// 编辑素材。
    func mediaAlbumEdit(_ request: MediaAlbumEditRequest) async throws

    /// 获取样片上传可关联的项目列表。
    func projectList(scenicId: Int, name: String?, page: Int, pageSize: Int) async throws -> ListPayload<PhotographerProjectItem>

    /// 获取相册文件夹列表。
    func albumFolderList(scenicId: Int, page: Int, pageSize: Int, name: String, startTime: String?, endTime: String?) async throws -> ListPayload<AlbumFolderItem>

    /// 获取相册文件夹详情。
    func albumFolderInfo(id: Int) async throws -> AlbumFolderItem

    /// 获取相册内文件列表。
    func albumFileList(scenicId: Int, folderId: Int, fileType: Int, page: Int, pageSize: Int) async throws -> ListPayload<AlbumFileItem>

    /// 新建相册文件夹。
    func addAlbumFolder(scenicId: Int, name: String, remark: String) async throws

    /// 编辑相册文件夹名称、备注或封面。
    func editAlbumFolder(folderId: Int, coverFileId: Int?, name: String?, remark: String?) async throws

    /// 删除相册内文件。
    func deleteAlbumFiles(folderId: Int, idList: [Int]) async throws

    /// 登记已上传到 OSS 的相册文件。
    func albumFileUploadURL(scenicId: Int, fileURL: String, folderId: Int) async throws
}

/// 资产 API，负责封装相册云盘和素材管理相关接口。
@MainActor
final class AssetsAPI: AssetsServing {
    private let client: APIClient

    /// 初始化资产 API，并注入共享网络客户端。
    init(client: APIClient) {
        self.client = client
    }

    /// 获取云盘文件列表。
    func cloudFileList(
        parentFolderId: Int,
        name: String = "",
        type: Int = 0,
        orderBy: Int = 2,
        page: Int = 1,
        pageSize: Int = 20
    ) async throws -> ListPayload<CloudDriveFile> {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/cloud-driver/list",
                queryItems: [
                    URLQueryItem(name: "parent_folder_id", value: "\(parentFolderId)"),
                    URLQueryItem(name: "name", value: name),
                    URLQueryItem(name: "type", value: "\(type)"),
                    URLQueryItem(name: "order_by", value: "\(orderBy)"),
                    URLQueryItem(name: "page", value: "\(max(page, 1))"),
                    URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))")
                ]
            )
        )
    }

    /// 创建云盘文件夹。
    func cloudFolderCreate(_ request: CloudFolderCreateRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/folder-create", body: request)
        ) as EmptyPayload
    }

    /// 登记已上传到 OSS 的云盘文件。
    func cloudFileUpload(_ request: CloudFileUploadRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/file-upload", body: request)
        ) as EmptyPayload
    }

    /// 删除云盘文件或文件夹。
    func cloudFileDelete(_ request: CloudFileDeleteRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/delete", body: request)
        ) as EmptyPayload
    }

    /// 移动云盘文件或文件夹。
    func cloudFileMove(_ request: CloudFileMoveRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/move", body: request)
        ) as EmptyPayload
    }

    /// 重命名云盘文件夹。
    func cloudFolderEdit(_ request: CloudFolderModifyRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/folder-edit", body: request)
        ) as EmptyPayload
    }

    /// 重命名云盘文件。
    func cloudFileEdit(_ request: CloudFileModifyRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/cloud-driver/file-edit", body: request)
        ) as EmptyPayload
    }

    /// 检查当前账号是否允许上传云盘文件。
    func checkCloudUploadPermission() async throws -> CheckCloudUploadResponse {
        try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/cloud-driver/check-upload-permission")
        )
    }

    /// 获取素材或样片列表。
    func mediaAlbumList(
        kind: MediaLibraryKind = .material,
        keyword: String = "",
        status: Int? = nil,
        page: Int = 1,
        pageSize: Int = 10
    ) async throws -> MediaLibraryListResponse {
        var query = [
            URLQueryItem(name: "type", value: "\(kind.rawValue)"),
            URLQueryItem(name: "keyword", value: keyword),
            URLQueryItem(name: "page", value: "\(max(page, 1))"),
            URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))")
        ]
        if let status, status >= 0 {
            query.append(URLQueryItem(name: "status", value: "\(status)"))
        }
        return try await client.send(
            APIRequest(method: .get, path: "/api/app/media-album/list", queryItems: query)
        )
    }

    /// 获取素材或样片详情。
    func mediaAlbumDetail(id: Int, kind: MediaLibraryKind = .material) async throws -> MediaLibraryDetail {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/app/media-album/detail",
                queryItems: [
                    URLQueryItem(name: "id", value: "\(id)"),
                    URLQueryItem(name: "type", value: "\(kind.rawValue)")
                ]
            )
        )
    }

    /// 更新素材或样片上下架状态。
    func mediaAlbumOperation(_ request: MediaAlbumOperationRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/app/media-album/operation", body: request)
        ) as EmptyPayload
    }

    /// 删除素材或样片。
    func mediaAlbumDelete(_ request: MediaAlbumDeleteRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/app/media-album/delete", body: request)
        ) as EmptyPayload
    }

    /// 新增素材标签。
    func mediaAlbumAddTag(_ request: MediaAlbumAddTagRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/app/media-album/add-tag", body: request)
        ) as EmptyPayload
    }

    /// 上传素材或样片。
    func mediaAlbumUpload(_ request: MediaAlbumUploadRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/app/media-album/upload", body: request)
        ) as EmptyPayload
    }

    /// 编辑素材。
    func mediaAlbumEdit(_ request: MediaAlbumEditRequest) async throws {
        _ = try await client.send(
            APIRequest(method: .post, path: "/api/app/media-album/edit", body: request)
        ) as EmptyPayload
    }

    /// 获取样片上传可关联的项目列表。
    func projectList(
        scenicId: Int,
        name: String? = nil,
        page: Int = 1,
        pageSize: Int = 50
    ) async throws -> ListPayload<PhotographerProjectItem> {
        var query = [
            URLQueryItem(name: "scenic_id", value: "\(scenicId)"),
            URLQueryItem(name: "page", value: "\(max(page, 1))"),
            URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))")
        ]
        if let name, !name.isEmpty {
            query.append(URLQueryItem(name: "name", value: name))
        }
        return try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/project/list", queryItems: query)
        )
    }

    /// 获取相册文件夹列表。
    func albumFolderList(
        scenicId: Int,
        page: Int = 1,
        pageSize: Int = 10,
        name: String = "",
        startTime: String? = nil,
        endTime: String? = nil
    ) async throws -> ListPayload<AlbumFolderItem> {
        var query = [
            URLQueryItem(name: "scenic_id", value: "\(scenicId)"),
            URLQueryItem(name: "page", value: "\(max(page, 1))"),
            URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))"),
            URLQueryItem(name: "cloud_folder_type", value: "1")
        ]
        if !name.isEmpty {
            query.append(URLQueryItem(name: "name", value: name))
        }
        if let startTime, !startTime.isEmpty {
            query.append(URLQueryItem(name: "start_time", value: startTime))
        }
        if let endTime, !endTime.isEmpty {
            query.append(URLQueryItem(name: "end_time", value: endTime))
        }
        return try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/album/folder-list", queryItems: query)
        )
    }

    /// 获取相册文件夹详情。
    func albumFolderInfo(id: Int) async throws -> AlbumFolderItem {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/album/folder-info",
                queryItems: [URLQueryItem(name: "id", value: "\(id)")]
            )
        )
    }

    /// 获取相册内文件列表。
    func albumFileList(
        scenicId: Int,
        folderId: Int,
        fileType: Int,
        page: Int = 1,
        pageSize: Int = 20
    ) async throws -> ListPayload<AlbumFileItem> {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/album/file-list",
                queryItems: [
                    URLQueryItem(name: "scenic_id", value: "\(scenicId)"),
                    URLQueryItem(name: "folder_id", value: "\(folderId)"),
                    URLQueryItem(name: "file_type", value: "\(fileType)"),
                    URLQueryItem(name: "page", value: "\(max(page, 1))"),
                    URLQueryItem(name: "page_size", value: "\(max(pageSize, 1))")
                ]
            )
        )
    }

    /// 新建相册文件夹。
    func addAlbumFolder(scenicId: Int, name: String, remark: String) async throws {
        _ = try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/album/folder-add",
                body: AlbumFolderAddRequest(
                    scenicId: "\(scenicId)",
                    name: name,
                    remark: remark,
                    cloudFolderType: 1
                )
            )
        ) as EmptyPayload
    }

    /// 编辑相册文件夹名称、备注或封面。
    func editAlbumFolder(folderId: Int, coverFileId: Int? = nil, name: String? = nil, remark: String? = nil) async throws {
        _ = try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/album/folder-edit",
                body: AlbumFolderEditRequest(folderId: folderId, coverFileId: coverFileId, name: name, remark: remark)
            )
        ) as EmptyPayload
    }

    /// 删除相册内文件。
    func deleteAlbumFiles(folderId: Int, idList: [Int]) async throws {
        _ = try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/album/file-delete",
                body: AlbumFileDeleteRequest(idList: idList, folderId: folderId)
            )
        ) as EmptyPayload
    }

    /// 登记已上传到 OSS 的相册文件。
    func albumFileUploadURL(scenicId: Int, fileURL: String, folderId: Int) async throws {
        _ = try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/album/file-upload-url",
                queryItems: [
                    URLQueryItem(name: "scenic_id", value: "\(scenicId)"),
                    URLQueryItem(name: "file_url", value: fileURL),
                    URLQueryItem(name: "folder_id", value: "\(folderId)")
                ]
            )
        ) as EmptyPayload
    }
}
