import APIClient
import ComponentLibrary
import ComposableArchitecture
import FeatureClipList
import Localization
import NavigationRouterClient
import SwiftUI
import Utilities

@Reducer
public struct FollowList {
    @ObservableState
    public struct State: Equatable {
        public enum FollowListType {
            case following
            case followers

            var title: String {
                switch self {
                case .following: L10n.FeatureSocial.following
                case .followers: L10n.FeatureSocial.followers
                }
            }
        }

        @ObservationStateIgnored @ObservedBox var profileList: ProfileList.State = .init(firstPageIndex: 1)
        let handle: String
        let type: FollowListType
        var loadState: LoadState { profileList.loadState }

        @Shared(.inMemory(.isCompactPlayerVisible)) fileprivate var isCompactPlayerVisible = false

        public init(handle: String, type: FollowListType) {
            self.handle = handle
            self.type = type
        }
    }

    public enum Action {
        case task
        case profileList(ProfileList.Action)
    }

    @Dependency(\.apiClientV2) var api
    @Dependency(NavigationRouterClient.self) private var navigationRouter

    public init() {}

    public var body: some ReducerOf<Self> {
        Scope(state: \.profileList, action: \.profileList) {
            ProfileList()
        }
        .withProfileListClient { state in
            .init(getProfiles: { page in
                do {
                    switch state.type {
                    case .followers:
                        let result = try await api.getFollowers(handle: state.handle, page: page)
                        return result

                    case .following:
                        let result = try await api.getFollowing(handle: state.handle, page: page)
                        return result
                    }
                }
            })
        }
        Reduce { _, action in
            switch action {
            case .task:
                return .send(.profileList(.loadProfiles))

            case .profileList(.profiles(.element(_, action: .authorTapped(let handle)))):
                navigationRouter.send(route: .profile(handle))
                return .none

            case .profileList:
                return .none
            }
        }
    }
}

public struct FollowListScreen: View {
    let store: StoreOf<FollowList>

    public init(store: StoreOf<FollowList>) {
        self.store = store
    }

    public var body: some View {
        Group {
            switch store.profileList.loadState {
            case .loading:
                LoadingView()
            case .loaded:
                loadedView
            case .failed(let message):
                FailedView(
                    title: L10n.FeatureSocial.errorTitle,
                    message: message,
                    buttonTitle: L10n.FeatureSocial.retry,
                    action: { store.send(.task) }
                )
            }
        }
        .navigationBarTitleDisplayMode(.inline)
        .navigationBarTitle(store.type.title)
        .background(Color.SemanticV1.backgroundPrimary)
        .task {
            store.send(.task)
        }
    }

    private var loadedView: some View {
        List {
            Section {
                ProfileListContent(store: store.scope(state: \.profileList, action: \.profileList)) { _, item in
                    item
                }
            }
            .listRowBackground(Color.clear)
            .listSectionSeparator(.hidden, edges: .top)
            .listSectionSpacing(.zero)
            .listRowInsets(.init())
            .textCase(nil)
        }
        .listStyle(.grouped)
        .scrollContentBackground(.hidden)
        .contentMargins(.horizontal, 12, for: .scrollContent)
        .omniPlayerSafeArea(includeTabBar: true)
    }
}
