//
//  GetAppStoreVersionPhasedRelease.swift
//  AppStoreConnect-Swift-SDK
//
//  Created by James Sherlock on 14/12/2020.
//

import Foundation
#if os(Linux)
import FoundationNetworking
#endif

extension APIEndpoint where T == AppStoreVersionPhasedReleaseResponse {
    /// Get the app store phased release status for a specifi version.
    ///
    /// - Parameters:
    ///   - id: An opaque resource ID that uniquely identifies the resource.
    ///   - fields: Fields to return for included related types.
    public static func appStoreVersionPhasedRelease(
        ofVersionWithId id: String,
        fields: [GetAppStoreVersionPhasedRelease.Field]? = nil
    ) -> APIEndpoint {
        var parameters = [String: Any]()
        if let fields = fields { parameters.add(fields) }

        return APIEndpoint(
            path: "appStoreVersions/\(id)/appStoreVersionPhasedRelease",
            method: .get,
            parameters: parameters)
    }

    public static func create(id: String) -> APIEndpoint {
        let request = AppStoreVersionPhasedReleaseCreateRequest(
            id: id,
            phasedReleaseState: .active
        )
        return APIEndpoint(
            path: "appStoreVersionPhasedReleases",
            method: .post,
            parameters: nil,
            body: try? JSONEncoder().encode(request)
        )
    }

    public static func modify(id: String, phasedReleaseState: PhasedReleaseState) -> APIEndpoint {
        let request = AppStoreVersionPhasedReleaseUpdateRequest(id: id, phasedReleaseState: phasedReleaseState)
        return APIEndpoint(
            path: "appStoreVersionPhasedReleases/\(id)",
            method: .patch,
            parameters: nil,
            body: try? JSONEncoder().encode(request)
        )
    }
}

public struct AppStoreVersionPhasedReleaseCreateRequest: Codable {
    let data: AppStoreVersionPhasedReleaseCreateRequest.Data
    public init(id: String, phasedReleaseState: PhasedReleaseState) {
        self.data = .init(
            attributes: .init(phasedReleaseState: phasedReleaseState),
            relationships: .init(appStoreVersion: .init(data: .init(id: id)))
        )
    }
}
extension AppStoreVersionPhasedReleaseCreateRequest {
    public struct Data: Codable {
        let attributes: AppStoreVersionPhasedReleaseCreateRequest.Data.Attributes

        let relationships: AppStoreVersionPhasedReleaseCreateRequest.Data.Relationships

        let type: String = "appStoreVersionPhasedReleases"
    }
}
extension AppStoreVersionPhasedReleaseCreateRequest.Data {
    public struct Attributes: Codable {
        let phasedReleaseState: PhasedReleaseState
    }
    public struct Relationships: Codable {
        let appStoreVersion: AppStoreVersionPhasedReleaseCreateRequest.Data.Relationships.AppStoreVersion
    }
}
extension AppStoreVersionPhasedReleaseCreateRequest.Data.Relationships {
    public struct AppStoreVersion: Codable {
        let data: AppStoreVersionPhasedReleaseCreateRequest.Data.Relationships.AppStoreVersion.Data
    }
}
extension AppStoreVersionPhasedReleaseCreateRequest.Data.Relationships.AppStoreVersion {
    public struct Data: Codable {
        let id: String
        let type: String = "appStoreVersions"
    }
}

public struct AppStoreVersionPhasedReleaseUpdateRequest: Codable {
    let data: AppStoreVersionPhasedReleaseUpdateRequest.Data
    public init(id: String, phasedReleaseState: PhasedReleaseState) {
        self.data = .init(id: id, attributes: .init(phasedReleaseState: phasedReleaseState))
    }
}
extension AppStoreVersionPhasedReleaseUpdateRequest {
    public struct Data: Codable {
        let id: String
        let attributes: AppStoreVersionPhasedReleaseUpdateRequest.Data.Attributes
        let type: String = "appStoreVersionPhasedReleases"
    }
}

extension AppStoreVersionPhasedReleaseUpdateRequest.Data {
    public struct Attributes: Codable {
        let phasedReleaseState: PhasedReleaseState
    }
}


public enum GetAppStoreVersionPhasedRelease {
    /// Fields to return for included related types.
    public enum Field: NestableQueryParameter {
        public enum Value: String, CaseIterable {
            case currentDayNumber
            case phasedReleaseState
            case startDate
            case totalPauseDuration
        }

        case appStoreVersionPhasedReleases([Value])

        static var key: String = "fields"
        var pair: Pair {
            switch self {
            case .appStoreVersionPhasedReleases(let values):
                return ("appStoreVersionPhasedReleases", values.map(\.rawValue).joinedByCommas())
            }
        }
    }
}
