//
//  CommentView.swift
//  Yattee
//
//  View displaying a single comment.
//

import SwiftUI
import NukeUI

struct CommentView: View {
    @Environment(\.appEnvironment) private var appEnvironment

    let comment: Comment
    let videoID: String?
    let source: ContentSource?
    let isReply: Bool

    @State private var replies: [Comment] = []
    @State private var isLoadingReplies = false
    @State private var showReplies = false
    @State private var repliesContinuation: String?

    private var contentService: ContentService? { appEnvironment?.contentService }
    private var instancesManager: InstancesManager? { appEnvironment?.instancesManager }
    private var navigationCoordinator: NavigationCoordinator? { appEnvironment?.navigationCoordinator }
    private var accentColor: Color { appEnvironment?.settingsManager.resolvedAccentColor ?? .accentColor }

    init(comment: Comment, videoID: String? = nil, source: ContentSource? = nil, isReply: Bool = false) {
        self.comment = comment
        self.videoID = videoID
        self.source = source
        self.isReply = isReply
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            HStack(alignment: .top, spacing: 12) {
                // Author avatar
                authorAvatar

                VStack(alignment: .leading, spacing: 4) {
                    // Author name and badges
                    authorInfo

                    // Comment content — render with clickable URLs and timestamps
                    Text(DescriptionText.attributed(comment.content, linkColor: accentColor))
                        #if os(macOS)
                        .font(.body)
                        #else
                        .font(.subheadline)
                        #endif
                        .foregroundStyle(.primary)
                        .fixedSize(horizontal: false, vertical: true)
                        #if !os(tvOS)
                        .textSelection(.enabled)
                        .handleTimestampLinks(using: appEnvironment?.playerService)
                        #endif

                    // Metadata row
                    metadataRow
                }
            }
            .padding(.vertical, 8)

            // Replies section (only for top-level comments)
            if !isReply && comment.replyCount > 0 {
                repliesSection
            }
        }
    }

    @ViewBuilder
    private var authorAvatar: some View {
        #if os(tvOS)
        authorAvatarImage
        #else
        Button {
            navigateToChannel()
        } label: {
            authorAvatarImage
        }
        .buttonStyle(.plain)
        #endif
    }

    @ViewBuilder
    private var authorAvatarImage: some View {
        LazyImage(url: comment.author.thumbnailURL) { state in
            if let image = state.image {
                image
                    .resizable()
                    .aspectRatio(contentMode: .fill)
            } else {
                Circle()
                    .fill(.quaternary)
                    .overlay {
                        Text(String(comment.author.name.prefix(1)))
                            .font(.caption)
                            .fontWeight(.medium)
                            .foregroundStyle(.secondary)
                    }
            }
        }
        .frame(width: 32, height: 32)
        .clipShape(Circle())
    }

    @ViewBuilder
    private var authorInfo: some View {
        HStack(spacing: 4) {
            Text(comment.author.name)
                #if os(macOS)
                .font(.subheadline)
                #else
                .font(.caption)
                #endif
                .fontWeight(.semibold)
                .foregroundStyle(comment.isCreatorComment ? accentColor : .primary)

            if comment.isCreatorComment {
                Image(systemName: "checkmark.seal.fill")
                    .font(.caption2)
                    .foregroundStyle(accentColor)
            }

            if comment.isPinned {
                Image(systemName: "pin.fill")
                    .font(.caption2)
                    .foregroundStyle(.secondary)
            }
        }
    }

    private func navigateToChannel() {
        guard let source, !comment.author.id.isEmpty else { return }
        // Set collapsing first so mini player shows video immediately
        navigationCoordinator?.isPlayerCollapsing = true
        navigationCoordinator?.isPlayerExpanded = false
        navigationCoordinator?.navigate(to: .channel(comment.author.id, source))
    }

    @ViewBuilder
    private var metadataRow: some View {
        HStack(spacing: 12) {
            // Published time
            if let publishedText = comment.formattedPublishedDate {
                Text(publishedText)
                    #if os(macOS)
                    .font(.subheadline)
                    #else
                    .font(.caption)
                    #endif
                    .foregroundStyle(.secondary)
            }

            // Like count
            if let likeCount = comment.formattedLikeCount {
                HStack(spacing: 2) {
                    Image(systemName: "hand.thumbsup")
                        #if os(macOS)
                        .font(.caption)
                        #else
                        .font(.caption2)
                        #endif
                    Text(likeCount)
                        #if os(macOS)
                        .font(.subheadline)
                        #else
                        .font(.caption)
                        #endif
                }
                .foregroundStyle(.secondary)
            }

            // Creator heart
            if comment.hasCreatorHeart {
                Image(systemName: "heart.fill")
                    .font(.caption2)
                    .foregroundStyle(.red)
            }
        }
    }

    // MARK: - Replies Section

    @ViewBuilder
    private var repliesSection: some View {
        VStack(alignment: .leading, spacing: 0) {
            // Toggle replies button
            Button {
                withAnimation(.easeInOut(duration: 0.2)) {
                    if showReplies {
                        showReplies = false
                    } else {
                        showReplies = true
                        if replies.isEmpty {
                            Task { await loadReplies() }
                        }
                    }
                }
            } label: {
                HStack(spacing: 4) {
                    Image(systemName: "chevron.down")
                        .font(.caption2)
                        .rotationEffect(.degrees(showReplies ? -180 : 0))
                    Text(String(localized: "comments.showReplies \(comment.replyCount)"))
                        #if os(macOS)
                        .font(.subheadline)
                        #else
                        .font(.caption)
                        #endif
                        .fontWeight(.medium)
                }
                #if !os(tvOS)
                .foregroundStyle(accentColor)
                #endif
            }
            .buttonStyle(.plain)
            .padding(.leading, 44) // Align with comment content (avatar width + spacing)
            .padding(.bottom, 8)

            // Replies list
            if showReplies {
                VStack(alignment: .leading, spacing: 0) {
                    ForEach(replies) { reply in
                        CommentView(comment: reply, source: source, isReply: true)
                            .padding(.leading, 44)

                        if reply.id != replies.last?.id {
                            Divider()
                                .padding(.leading, 44)
                        }
                    }

                    // Load more replies
                    if isLoadingReplies {
                        HStack {
                            Spacer()
                            ProgressView()
                                .padding(.vertical, 8)
                            Spacer()
                        }
                        .padding(.leading, 44)
                    } else if repliesContinuation != nil {
                        Button {
                            Task { await loadReplies() }
                        } label: {
                            Text(String(localized: "comments.loadMoreReplies"))
                                #if os(macOS)
                                .font(.subheadline)
                                #else
                                .font(.caption)
                                #endif
                                .fontWeight(.medium)
                                #if !os(tvOS)
                                .foregroundStyle(accentColor)
                                #endif
                        }
                        .buttonStyle(.plain)
                        .padding(.leading, 44)
                        .padding(.vertical, 8)
                    }
                }
            }
        }
    }

    private func loadReplies() async {
        guard let videoID, let contentService, let instancesManager else { return }
        guard let instance = instancesManager.enabledInstances.first(where: \.isYouTubeInstance) else { return }

        // Use the comment's replies continuation, or the stored one for subsequent pages
        let continuation = replies.isEmpty ? comment.repliesContinuation : repliesContinuation
        guard let continuation else { return }

        isLoadingReplies = true

        do {
            let page = try await contentService.comments(videoID: videoID, instance: instance, continuation: continuation)
            replies.append(contentsOf: page.comments)
            repliesContinuation = page.continuation
        } catch {
            // Silently fail for replies
        }

        isLoadingReplies = false
    }
}
