import SwiftUI
import PDFKit

struct PDFKitView: UIViewRepresentable {
    let document: PDFDocument
    @Binding var pageIndex: Int

    func makeUIView(context: Context) -> PDFView {
        let view = PDFView()
        view.autoScales = true
        view.displayMode = .singlePageContinuous
        view.displayDirection = .vertical
        view.document = document
        context.coordinator.pdfView = view
        context.coordinator.bindNotifications(for: view)
        goToPage(pageIndex, in: view)
        return view
    }

    func updateUIView(_ uiView: PDFView, context: Context) {
        if uiView.document !== document {
            uiView.document = document
        }
        if context.coordinator.isUserScrolling { return }
        goToPage(pageIndex, in: uiView)
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(pageIndex: $pageIndex)
    }

    static func dismantleUIView(_ uiView: PDFView, coordinator: Coordinator) {
        coordinator.unbindNotifications()
    }

    private func goToPage(_ index: Int, in view: PDFView) {
        let pageCount = document.pageCount
        guard pageCount > 0 else { return }
        let clamped = min(max(1, index), pageCount)
        if let page = document.page(at: clamped - 1) {
            view.go(to: page)
        }
    }

    final class Coordinator {
        var pageIndex: Binding<Int>
        weak var pdfView: PDFView?
        var isUserScrolling = false
        private var observer: NSObjectProtocol?

        init(pageIndex: Binding<Int>) {
            self.pageIndex = pageIndex
        }

        func bindNotifications(for view: PDFView) {
            unbindNotifications()
            observer = NotificationCenter.default.addObserver(
                forName: .PDFViewPageChanged,
                object: view,
                queue: .main
            ) { [weak self] _ in
                guard let self, let pdfView = self.pdfView,
                      let page = pdfView.currentPage,
                      let document = pdfView.document else { return }
                let idx = document.index(for: page) + 1
                self.isUserScrolling = true
                self.pageIndex.wrappedValue = idx
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                    self.isUserScrolling = false
                }
            }
        }

        func unbindNotifications() {
            if let observer {
                NotificationCenter.default.removeObserver(observer)
                self.observer = nil
            }
        }

        deinit {
            unbindNotifications()
        }
    }
}
