//
//  LNProfileUserDetailView.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/15.
//

import Foundation
import UIKit
import SnapKit
import Combine


protocol LNProfileUserDetailViewDelegate: AnyObject {
    func onProfileUserDetailView(view: LNProfileUserDetailView, contentHeightChanged height: CGFloat)
}


class LNProfileUserDetailView: UIView {
    private(set) var contentHeight: CGFloat = 0.0 {
        didSet {
            delegate?.onProfileUserDetailView(view: self, contentHeightChanged: contentHeight)
        }
    }
    
    private let tableView = LNNestedTableView(frame: .zero, style: .grouped)
    private let providers: [LNProfileBaseProvider] = [
        LNProfileUserInfoProvider(),
        LNProfileSkillListProvider(),
        LNProfileFeedProvider()
    ]
    private var availableProviders: [LNProfileBaseProvider] = []
    
    private var curDetail: LNUserProfileVO?
    weak var delegate: LNProfileUserDetailViewDelegate?
    weak var outerScrollView: LNNestedScrollViewDelegate? {
        didSet {
            tableView.observerDelegate = outerScrollView
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
    }
    
    override func didMoveToWindow() {
        super.didMoveToWindow()
        
        if window != nil {
            availableProviders.forEach { $0.onAppear() }
        } else {
            availableProviders.forEach { $0.onDisappear() }
        }
    }
    
    func update(_ detail: LNUserProfileVO) {
        providers.forEach { $0.update(detail) }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNProfileUserDetailView: UITableViewDataSource, UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        availableProviders.removeAll()
        availableProviders.append(contentsOf: providers.filter({ $0.numberOfCell > 0 }))
        
        return availableProviders.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        availableProviders[section].numberOfCell
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        availableProviders[indexPath.section].buildCell(tableView: tableView, indexPath: indexPath)
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let container = UIView()
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h3
        titleLabel.textColor = .text_5
        titleLabel.text = availableProviders[section].title
        container.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalToSuperview().offset(16)
        }
        
        return container
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        0
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        nil
    }
    
    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        availableProviders.forEach { ($0 as? UITableViewDelegate)?.tableView?(tableView, didEndDisplaying: cell, forRowAt: indexPath) }
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        availableProviders.forEach { ($0 as? UIScrollViewDelegate)?.scrollViewDidEndDecelerating?(scrollView) }
    }
    
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        availableProviders.forEach { ($0 as? UIScrollViewDelegate)?.scrollViewDidEndScrollingAnimation?(scrollView) }
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        availableProviders.forEach { ($0 as? UIScrollViewDelegate)?.scrollViewDidEndDragging?(scrollView, willDecelerate: decelerate) }
    }
}

extension LNProfileUserDetailView {
    private func setupViews() {
        tableView.tableDelegate = self
        tableView.dataSource = self
        tableView.allowsSelection = false
        tableView.backgroundColor = .white
        tableView.showsVerticalScrollIndicator = false
        tableView.showsHorizontalScrollIndicator = false
        tableView.separatorStyle = .none
        tableView.contentInset = .init(top: 16, left: 0, bottom: 0, right: 0)
        tableView.bounces = false
        tableView.publisher(for: \.contentSize).removeDuplicates().sink
        { [weak self] newValue in
            guard let self else { return }
            contentHeight = newValue.height + tableView.contentInset.top + tableView.contentInset.bottom
        }.store(in: &cancellables)
        addSubview(tableView)
        tableView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        providers.forEach { $0.registerCell(tableView: tableView) }
        tableView.reloadData()
    }
}
