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

import Foundation
import CombineMoya
import Combine
import Moya

final class ContentRepository {
    private let api = MoyaProvider<ContentApi>()
    private let categoryApi = MoyaProvider<CategoryApi>()
    private let explorerApi = MoyaProvider<ExplorerApi>()
    
    func getAudioContentList(userId: Int, categoryId: Int,  page: Int, size: Int, sort: ContentListViewModel.Sort) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getAudioContentList(
                userId: userId,
                categoryId: categoryId,
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                page: page,
                size: size,
                sort: sort)
        )
    }
    
    func getAudioContentDetail(audioContentId: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getAudioContentDetail(audioContentId: audioContentId))
    }
    
    func likeContent(audioContentId: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.likeContent(request: PutAudioContentLikeRequest(contentId: audioContentId)))
    }
    
    func registerComment(audioContentId: Int, comment: String, parentId: Int? = nil, isSecret: Bool = false) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.registerComment(request: RegisterAudioContentCommentRequest(comment: comment, contentId: audioContentId, parentId: parentId, isSecret: isSecret)))
    }
    
    func orderAudioContent(contentId: Int, orderType: OrderType) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.orderAudioContent(request: OrderRequest(contentId: contentId, orderType: orderType)))
    }
    
    func getOrderList(page: Int, size: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getOrderList(page: page, size: size))
    }
    
    func addAllPlaybackTracking(request: AddAllPlaybackTrackingRequest) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.addAllPlaybackTracking(request: request))
    }
    
    func getAudioContentThemeList() -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getAudioContentThemeList)
    }
    
    func uploadAudioContent(parameters: [MultipartFormData]) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.uploadAudioContent(parameters: parameters))
    }
    
    func getAudioContentCommentList(audioContentId: Int, page: Int, size: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getAudioContentCommentList(audioContentId: audioContentId, page: page, size: size))
    }
    
    func getAudioContentCommentReplyList(commentId: Int, page: Int, size: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getAudioContentCommentReplyList(commentId: commentId, page: page, size: size))
    }
    
    func deleteAudioContent(audioContentId: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.deleteAudioContent(audioContentId: audioContentId))
    }
    
    func modifyAudioContent(parameters: [MultipartFormData]) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.modifyAudioContent(parameters: parameters))
    }
    
    func getNewContentUploadCreatorList() -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getNewContentUploadCreatorList)
    }
    
    func getMainBannerList() -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getMainBannerList)
    }
    
    func getMainOrderList() -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getMainOrderList)
    }
    
    func getNewContentOfTheme(theme: String) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getNewContentOfTheme(
                theme: theme,
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL
            )
        )
    }
    
    func getCurationList(page: Int, size: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getCurationList(
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL,
                page: page,
                size: size
            )
        )
    }
    
    func donation(contentId: Int, can: Int, comment: String) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.donation(request: AudioContentDonationRequest(contentId: contentId, donationCan: can, comment: comment)))
    }
    
    func modifyComment(request: ModifyCommentRequest) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.modifyComment(request: request))
    }
    
    func getNewContentThemeList() -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getNewContentThemeList(
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL
            )
        )
    }
    
    func getNewContentAllOfTheme(isFree: Bool, theme: String, page: Int, size: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getNewContentAllOfTheme(
                isFree: isFree,
                theme: theme,
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL,
                page: page,
                size: size
            )
        )
    }
    
    func getAudioContentListByCurationId(curationId: Int, page: Int, size: Int, sort: ContentCurationViewModel.Sort) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getAudioContentListByCurationId(
                curationId: curationId,
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL,
                page: page,
                size: size,
                sort: sort
            )
        )
    }
    
    func getContentRankingSortType() -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.getContentRankingSortType)
    }
    
    func getContentRanking(page: Int, size: Int, sortType: String = "매출") -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getContentRanking(
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL,
                page: page,
                size: size,
                sortType: sortType
            )
        )
    }
    
    func pinContent(contentId: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.pinContent(contentId: contentId))
    }
    
    func unpinContent(contentId: Int) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(.unpinContent(contentId: contentId))
    }
    
    func getCategoryList(creatorId: Int) -> AnyPublisher<Response, MoyaError> {
        return categoryApi.requestPublisher(.getCategoryList(creatorId: creatorId))
    }
    
    func getAudioContentByTheme(themeId: Int, page: Int, size: Int, sort: ContentAllByThemeViewModel.Sort) -> AnyPublisher<Response, MoyaError> {
        return api.requestPublisher(
            .getAudioContentByTheme(
                themeId: themeId,
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL,
                page: page,
                size: size,
                sort: sort
            )
        )
    }
    
    func getCreatorRanking() -> AnyPublisher<Response, MoyaError> {
        return explorerApi.requestPublisher(.getCreatorRank)
    }
}