//
//  ContentApi.swift
//  SodaLive
//
//  Created by klaus on 2023/08/11.
//

import Foundation
import Moya

enum ContentApi {
    case getAudioContentList(userId: Int, categoryId: Int, page: Int, size: Int, sort: ContentListViewModel.Sort)
    case getAudioContentDetail(audioContentId: Int)
    case likeContent(request: PutAudioContentLikeRequest)
    case registerComment(request: RegisterAudioContentCommentRequest)
    case orderAudioContent(request: OrderRequest)
    case getOrderList(page: Int, size: Int)
    case addAllPlaybackTracking(request: AddAllPlaybackTrackingRequest)
    case getAudioContentThemeList
    case uploadAudioContent(parameters: [MultipartFormData])
    case getAudioContentCommentList(audioContentId: Int, page: Int, size: Int)
    case getAudioContentCommentReplyList(commentId: Int, page: Int, size: Int)
    case deleteAudioContent(audioContentId: Int)
    case modifyAudioContent(parameters: [MultipartFormData])
    case getNewContentUploadCreatorList
    case getMainBannerList
    case getMainOrderList
    case getNewContentOfTheme(theme: String, isAdultContentVisible: Bool, contentType: ContentType)
    case getCurationList(isAdultContentVisible: Bool, contentType: ContentType, page: Int, size: Int)
    case donation(request: AudioContentDonationRequest)
    case modifyComment(request: ModifyCommentRequest)
    case getNewContentThemeList
    case getNewContentAllOfTheme(theme: String, isAdultContentVisible: Bool, contentType: ContentType, page: Int, size: Int)
    case getAudioContentListByCurationId(curationId: Int, isAdultContentVisible: Bool, contentType: ContentType, page: Int, size: Int, sort: ContentCurationViewModel.Sort)
    case getContentRanking(page: Int, size: Int, sortType: String)
    case getContentRankingSortType
    case pinContent(contentId: Int)
    case unpinContent(contentId: Int)
    case getAudioContentByTheme(themeId: Int, isAdultContentVisible: Bool, contentType: ContentType, page: Int, size: Int, sort: ContentAllByThemeViewModel.Sort)
}

extension ContentApi: TargetType {
    var baseURL: URL {
        return URL(string: BASE_URL)!
    }
    
    var path: String {
        switch self {
        case .getAudioContentList:
            return "/audio-content"
            
        case .getAudioContentDetail(let audioContentId):
            return "/audio-content/\(audioContentId)"
            
        case .likeContent:
            return "/audio-content/like"
            
        case .registerComment:
            return "/audio-content/comment"
            
        case .orderAudioContent:
            return "/order/audio-content"
            
        case .getOrderList:
            return "/order/audio-content"
            
        case .addAllPlaybackTracking:
            return "/audio-content/playback-tracking"
            
        case .getAudioContentThemeList:
            return "/audio-content/theme"
            
        case .uploadAudioContent:
            return "/audio-content"
            
        case .getAudioContentCommentList(let audioContentId, _, _):
            return "/audio-content/\(audioContentId)/comment"
            
        case .getAudioContentCommentReplyList(let commentId, _, _):
            return "/audio-content/comment/\(commentId)"
            
        case .deleteAudioContent(let audioContentId):
            return "/audio-content/\(audioContentId)"
            
        case .modifyAudioContent:
            return "/audio-content"
            
        case .getNewContentUploadCreatorList:
            return "/audio-content/main/new-content-upload-creator"
            
        case .getMainBannerList:
            return "/audio-content/main/banner-list"
            
        case .getMainOrderList:
            return "/audio-content/main/order-list"
            
        case .getNewContentOfTheme:
            return "/audio-content/main/new"
            
        case .getCurationList:
            return "/audio-content/main/curation-list"
            
        case .donation:
            return "/audio-content/donation"
            
        case .modifyComment:
            return "/audio-content/comment"
            
        case .getNewContentThemeList:
            return "/audio-content/main/theme"
            
        case .getNewContentAllOfTheme:
            return "/audio-content/main/new/all"
            
        case .getAudioContentListByCurationId(let curationId, _, _, _, _, _):
            return "/audio-content/curation/\(curationId)"
            
        case .getContentRanking:
            return  "/audio-content/ranking"
            
        case .getContentRankingSortType:
            return  "/audio-content/ranking-sort-type"
            
        case .pinContent(let contentId):
            return  "/audio-content/pin-to-the-top/\(contentId)"
            
        case .unpinContent(let contentId):
            return  "/audio-content/unpin-at-the-top/\(contentId)"
            
        case .getAudioContentByTheme(let themeId, _, _, _, _, _):
            return "/audio-content/theme/\(themeId)/content"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .getAudioContentList, .getAudioContentDetail, .getOrderList, .getAudioContentThemeList,
                .getAudioContentCommentList, .getAudioContentCommentReplyList, .getNewContentOfTheme,
                .getNewContentThemeList, .getNewContentAllOfTheme, .getAudioContentListByCurationId, .getContentRanking,
                .getContentRankingSortType:
            return .get
            
        case .getMainBannerList, .getMainOrderList, .getNewContentUploadCreatorList, .getCurationList, .getAudioContentByTheme:
            return .get
            
        case .likeContent, .modifyAudioContent, .modifyComment, .unpinContent:
            return .put
            
        case .registerComment, .orderAudioContent, .addAllPlaybackTracking, .uploadAudioContent, .donation, .pinContent:
            return .post
            
        case .deleteAudioContent:
            return .delete
        }
    }
    
    var task: Moya.Task {
        switch self {
        case .getAudioContentList(let userId, let categoryId, let page, let size, let sort):
            let parameters = [
                "creator-id": userId,
                "category-id": categoryId,
                "page": page - 1,
                "size": size,
                "sort-type": sort
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getAudioContentDetail:
            let parameters = ["timezone": TimeZone.current.identifier] as [String : Any]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .likeContent(let request):
            return .requestJSONEncodable(request)
            
        case .registerComment(let request):
            return .requestJSONEncodable(request)
            
        case .orderAudioContent(let request):
            return .requestJSONEncodable(request)
            
        case .getOrderList(let page, let size):
            let parameters = [
                "page": page - 1,
                "size": size
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .addAllPlaybackTracking(let request):
            return .requestJSONEncodable(request)
            
        case .getAudioContentThemeList, .getMainBannerList, .getMainOrderList, .getNewContentUploadCreatorList:
            return .requestPlain
            
        case .uploadAudioContent(let parameters):
            return .uploadMultipart(parameters)
            
        case .modifyAudioContent(let parameters):
            return .uploadMultipart(parameters)
            
        case .getAudioContentCommentList(_, let page, let size):
            let parameters = [
                "page": page - 1,
                "size": size,
                "timezone": TimeZone.current.identifier
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getAudioContentCommentReplyList(_, let page, let size):
            let parameters = [
                "page": page - 1,
                "size": size,
                "timezone": TimeZone.current.identifier
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .deleteAudioContent:
            return .requestPlain
            
        case .getNewContentOfTheme(let theme, let isAdultContentVisible, let contentType):
            let parameters = [
                "theme": theme,
                "isAdultContentVisible": isAdultContentVisible,
                "contentType": contentType
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .donation(let request):
            return .requestJSONEncodable(request)
            
        case .modifyComment(let request):
            return .requestJSONEncodable(request)
            
        case .getNewContentThemeList:
            return .requestPlain
            
        case .getNewContentAllOfTheme(let theme, let isAdultContentVisible, let contentType, let page, let size):
            let parameters = [
                "theme": theme,
                "isAdultContentVisible": isAdultContentVisible,
                "contentType": contentType,
                "page": page - 1,
                "size": size
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getAudioContentListByCurationId(_, let isAdultContentVisible, let contentType, let page, let size, let sort):
            let parameters = [
                "isAdultContentVisible": isAdultContentVisible,
                "contentType": contentType,
                "page": page - 1,
                "size": size,
                "sort-type": sort
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getContentRanking(let page, let size, let sortType):
            let parameters = [
                "page": page - 1,
                "size": size,
                "sort-type": sortType
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getContentRankingSortType:
            return .requestPlain
            
        case .getCurationList(let isAdultContentVisible, let contentType, let page, let size):
            let parameters = [
                "isAdultContentVisible": isAdultContentVisible,
                "contentType": contentType,
                "page": page - 1,
                "size": size
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .pinContent, .unpinContent:
            return .requestPlain
            
        case .getAudioContentByTheme(_, let isAdultContentVisible, let contentType, let page, let size, let sort):
            let parameters = [
                "isAdultContentVisible": isAdultContentVisible,
                "contentType": contentType,
                "page": page - 1,
                "size": size,
                "sort-type": sort
            ] as [String : Any]
            
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
        }
    }
    
    var headers: [String : String]? {
        return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"]
    }
}
