import UIKit

@MainActor
final class ServerActivityViewController: RefreshingTableViewController {
    private let context: AppContext
    private var rows: [ActivityRow] = []
    private var nextPage: UInt32?
    private var loaded = false

    init(context: AppContext) {
        self.context = context
        super.init()
        title = "Server Activity"
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) { fatalError("init(coder:) is not supported") }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        guard !loaded else { return }
        loadContent(refreshing: false)
    }

    override func loadContent(refreshing: Bool) {
        loadPage(1, refreshing: refreshing)
    }

    override func loadMoreContent() {
        guard let nextPage else { return }
        loadPage(nextPage, refreshing: false)
    }

    private func loadPage(_ requestedPage: UInt32, refreshing: Bool) {
        if requestedPage == 1 {
            resetPagination()
            beginLoading(refreshing: refreshing)
        }
        loadingTask?.cancel()
        loadingTask = Task {
            do {
                let page = try await context.core.serverActivity(page: requestedPage)
                if requestedPage == 1 {
                    rows = page.rows
                    loaded = true
                } else {
                    rows.append(contentsOf: page.rows)
                }
                nextPage = page.hasMore ? requestedPage + 1 : nil
                finishPagination(hasMore: page.hasMore)
                updateRows()
            } catch {
                if !Task.isCancelled {
                    show(error: error)
                    failPagination()
                }
            }
            if requestedPage == 1 { endLoading() }
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        rows.count
    }

    override func tableView(
        _ tableView: UITableView,
        cellForRowAt indexPath: IndexPath
    ) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "server-activity")
            ?? UITableViewCell(style: .subtitle, reuseIdentifier: "server-activity")
        let row = rows[indexPath.row]
        configureTextCell(
            cell,
            title: row.title,
            detail: "\(row.detail)\n\(row.meta)",
            image: context.symbol(activitySymbolName(for: row.icon))
        )
        cell.accessoryType = row.target == .none ? .none : .disclosureIndicator
        cell.selectionStyle = row.target == .none ? .none : .default
        return cell
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        92
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let row = rows[indexPath.row]
        guard row.target != .none else { return }
        tableView.deselectRow(at: indexPath, animated: true)
        context.route(row)
    }

    private func updateRows() {
        tableView.reloadData()
        tableView.backgroundView = rows.isEmpty
            ? EmptyBackgroundView(
                title: "No server activity",
                detail: "No activity is visible to this server account."
            )
            : nil
    }
}
