//
//  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(isFree: Bool, 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)
    case generateUrl(contentId: Int)
    
    case getContentMainHome
    case getPopularContentByCreator(creatorId: Int)
    
    case getContentMainSeries
    case getRecommendSeriesListByGenre(genreId: Int)
    case getRecommendSeriesByCreator(creatorId: Int)
    case getCompletedSeries(page: Int, size: Int)
    
    case getContentMainContent
    case getContentMainNewContentOfTheme(theme: String, isAdultContentVisible: Bool, contentType: ContentType)
    case getDailyContentRanking(sortType: String)
    case getRecommendContentByTag(tag: String)
    case getContentMainContentPopularContentByCreator(creatorId: Int)
    
    case getContentMainAlarm
    case getContentMainAlarmAll(theme: String, page: Int, size: Int)
    
    case getContentMainAsmr
    case getPopularAsmrContentByCreator(creatorId: Int)
    
    case getContentMainReplay
    case getPopularReplayContentByCreator(creatorId: Int)
    
    case getContentMainFree
    case getIntroduceCreatorList(page: Int, size: Int)
    case getNewFreeContentOfTheme(theme: String, page: Int, size: Int)
    case getPopularFreeContentByCreator(creatorId: Int)
}

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"
            
        case .generateUrl(let contentId):
            return "/audio-content/\(contentId)/generate-url"
            
        case .getContentMainHome:
            return "/v2/audio-content/main/home"
            
        case .getPopularContentByCreator:
            return "/v2/audio-content/main/home/popular-content-by-creator"
            
        case .getContentMainSeries:
            return "/v2/audio-content/main/series"
            
        case .getRecommendSeriesListByGenre:
            return "/v2/audio-content/main/series/recommend-by-genre"
            
        case .getRecommendSeriesByCreator:
            return "/v2/audio-content/main/series/recommend-series-by-creator"
            
        case .getCompletedSeries:
            return "/v2/audio-content/main/series/completed-rank"
            
        case .getContentMainContent:
            return "/v2/audio-content/main/content"
            
        case .getContentMainNewContentOfTheme:
            return "/v2/audio-content/main/content/new-content-by-theme"
            
        case .getDailyContentRanking:
            return "/v2/audio-content/main/content/ranking"
            
        case .getRecommendContentByTag:
            return "/v2/audio-content/main/content/recommend-content-by-tag"
            
        case .getContentMainContentPopularContentByCreator:
            return "/v2/audio-content/main/content/popular-content-by-creator"
            
        case .getContentMainAlarm:
            return "/v2/audio-content/main/alarm"
            
        case .getContentMainAlarmAll:
            return "/v2/audio-content/main/alarm/all"
            
        case .getContentMainAsmr:
            return "/v2/audio-content/main/asmr"
            
        case .getPopularAsmrContentByCreator:
            return "/v2/audio-content/main/asmr/popular-content-by-creator"
            
        case .getContentMainReplay:
            return "/v2/audio-content/main/replay"
            
        case .getPopularReplayContentByCreator:
            return "/v2/audio-content/main/replay/popular-content-by-creator"
            
        case .getContentMainFree:
            return "/v2/audio-content/main/free"
            
        case .getIntroduceCreatorList:
            return "/v2/audio-content/main/free/introduce-creator"
            
        case .getNewFreeContentOfTheme:
            return "/v2/audio-content/main/free/new-content-by-theme"
            
        case .getPopularFreeContentByCreator:
            return "/v2/audio-content/main/free/popular-content-by-creator"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .getAudioContentList, .getAudioContentDetail, .getOrderList, .getAudioContentThemeList,
                .getAudioContentCommentList, .getAudioContentCommentReplyList, .getNewContentOfTheme,
                .getNewContentThemeList, .getNewContentAllOfTheme, .getAudioContentListByCurationId, .getContentRanking,
                .getContentRankingSortType, .generateUrl:
            return .get
            
        case .getMainBannerList, .getMainOrderList, .getNewContentUploadCreatorList, .getCurationList, .getAudioContentByTheme:
            return .get
            
        case .getContentMainHome, .getPopularContentByCreator, .getContentMainSeries, .getRecommendSeriesListByGenre, .getRecommendSeriesByCreator, .getContentMainContent,
                .getContentMainNewContentOfTheme, .getDailyContentRanking, .getRecommendContentByTag, .getContentMainAlarm, .getContentMainAlarmAll,
                .getContentMainAsmr, .getPopularAsmrContentByCreator, .getContentMainReplay, .getPopularReplayContentByCreator,
                .getContentMainFree, .getIntroduceCreatorList, .getNewFreeContentOfTheme, .getPopularFreeContentByCreator, .getCompletedSeries, .getContentMainContentPopularContentByCreator:
            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, .generateUrl:
            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 isFree, let theme, let isAdultContentVisible, let contentType, let page, let size):
            let parameters = [
                "isFree": isFree,
                "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)
            
        case .getContentMainHome, .getContentMainSeries, .getContentMainContent, 
                .getContentMainAlarm, .getContentMainAsmr, .getContentMainReplay, .getContentMainFree:
            return .requestPlain
            
        case .getRecommendSeriesListByGenre(let genreId):
            let parameters = ["genreId": genreId]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getPopularContentByCreator(let creatorId):
            let parameters = ["creatorId": creatorId]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getRecommendSeriesByCreator(let creatorId):
            let parameters = ["creatorId": creatorId]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getContentMainNewContentOfTheme(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 .getDailyContentRanking(let sortType):
            let parameters = ["sort-type": sortType]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getRecommendContentByTag(let tag):
            let parameters = ["tag": tag]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getContentMainContentPopularContentByCreator(let creatorId):
            let parameters = ["creatorId": creatorId]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getContentMainAlarmAll(let theme, let page, let size), .getNewFreeContentOfTheme(let theme, let page, let size):
            let parameters = [
                "theme": theme,
                "page": page - 1,
                "size": size
            ] as [String : Any]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getIntroduceCreatorList(let page, let size):
            let parameters = ["page": page - 1, "size": size]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getPopularAsmrContentByCreator(let creatorId), .getPopularReplayContentByCreator(let creatorId), .getPopularFreeContentByCreator(let creatorId):
            let parameters = ["creatorId": creatorId]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
            
        case .getCompletedSeries(let page, let size):
            let parameters = [
                "page": page - 1,
                "size": size
            ]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
        }
    }
    
    var headers: [String : String]? {
        return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"]
    }
}