import SwiftUI

struct AuthorView: View {
    enum ViewState: String, CaseIterable {
        case about
        case articles
        
        var title: String {
            rawValue.capitalized
        }
    }
    
    @EnvironmentObject var contentService: ContentService
    @EnvironmentObject var analyticsService: AnalyticsService
    
    var authorId: Int
    
    @State private var author: Author? = nil
    @State private var posts: [Post] = []
    
    @State var viewState: ViewState = .about
    @State private var bodyHeight: CGFloat = 0
    
    private var banner: Banner? {
        guard let authorName = author?.name else {
            return nil
        }
        
        return contentService.bannerForPosition(.author(authorName: authorName))
    }
    private var htmlContent: String {
        author?.bio ?? ""
    }
    
    var body: some View {
        ZStack {
            VStack {
                Spacer()
                ProgressView(label: {
                    Text("Loading content...")
                        .textStyle(.caption1)
                })
                .progressViewStyle(CircularProgressViewStyle())
                Spacer()
            }
            .opacity(author == nil ? 1 : 0)
            
            ScrollViewWithBanner(banner: banner, onRefresh: refreshPost, onLoadMore: loadMoreContent) { scrollProxy in
                VStack(alignment: .leading, spacing: 6) {
                    if viewState == .about {
                        VStack(alignment: .leading, spacing: 6) {
                            
                            HStack(spacing: 13) {
                                AvatarView(url: author?.avatar)
                                    .frame(width: 70, height: 70)
                                
                                Text(author?.name ?? "")
                                    .textStyle(.title3)
                                    .multilineTextAlignment(.leading)
                                    .lineLimit(nil)
                                
                                Spacer()
                            }
                            .padding(.vertical)
                            .padding(.horizontal, 10)
                            
                            if author != nil {
                                HTMLView(dynamicHeight: $bodyHeight, html: htmlContent, assets: [])
                                    .frame(height: bodyHeight)
                            }
                        }
                        .padding(.horizontal, 10)
                        
                    } else {
                        PostListingView(posts: posts, showYear: true)
                    }
                }
                .background(ColorName.background.color)
            }
            .opacity(author != nil ? 1 : 0)
        }
        .toolbar {
            ToolbarItem(placement: .principal) {
                let selection = Binding<Int> {
                    return ViewState.allCases.firstIndex(of: viewState) ?? 0
                } set: { newValue in
                    viewState = ViewState.allCases[newValue]
                }

                SegmentedControlView(selection: selection, items: ViewState.allCases.compactMap { $0.title })
                    .frame(width: UIDevice.current.userInterfaceIdiom == .pad ? 400 : 250 )
            }
            ToolbarItem(placement: .navigationBarTrailing) {
                ZStack {
                    Button(action: {
                        if let url = author?.link {
                            UIActivityViewController.shareSheet(url: url)
                        }
                    }, label: {
                        ImageName.System.share.image
                    })
                    .disabled(viewState != .about)
                    .opacity(viewState == .about ? 1 : 0)
                }
                .animation(.easeInOut, value: viewState)
            }
            
        }
        .onAppear {
            refreshPost()
            analyticsService.authorWasViewed(authorId: authorId)
        }
    }
    
    func refreshPost() {
        Task {
            do {
                let response = try await contentService.fetchAuthorDetails(authorId)
                
                self.author = response.author
                self.posts = response.posts
                self.pageToLoad = 2
            } catch {
                print(error)
            }
        }
    }
    
    @State private var pageToLoad: Int = 1
    @State private var isLoadingMore: Bool = false
    private func loadMoreContent() throws {
        
        Task {
            guard viewState == .articles,
                  !isLoadingMore else {
                return
            }
            
            isLoadingMore = true
            let response = try await contentService.fetchAuthorDetails(authorId, page: pageToLoad)
            DispatchQueue.main.async {
                self.posts = (self.posts + response.posts).unique()
                self.pageToLoad += 1
                isLoadingMore = false
            }
        }
    }
}

#if DEBUG
struct AuthorView_Previews: PreviewProvider {
    static var previews: some View {
        AuthorView(authorId: 1009376)
    }
}
#endif
