//
//  LNUserSearchViewController.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/12.
//

import Foundation
import UIKit
import SnapKit
import MJRefresh


extension UIView {
    func pushToUserSearch() {
        let vc = LNUserSearchViewController()
        navigationController?.pushViewController(vc, animated: true)
    }
}


class LNUserSearchViewController: LNViewController {
    private let searchInput = UITextField()
    
    private let historyView = LNUserSearchHistoryView()
    
    private let emptyView = LNNoMoreDataView()
    private let tableView = UITableView()
    
    private var curKeyword: String?
    private var nextTag: String?
    private var curList: [LNGameMateSearchResultVO] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupViews()
    }
}

extension LNUserSearchViewController {
    private func searchUser() {
        guard let curKeyword, !curKeyword.isEmpty else {
            tableView.mj_header?.endRefreshing()
            tableView.mj_footer?.endRefreshingWithNoMoreData()
            return
        }
        view.endEditing(true)
        
        historyView.isHidden = true
        historyView.addRecord(curKeyword)
        
        tableView.isHidden = false
        LNGameMateManager.shared.searchGameMate(keyword: curKeyword, next: nextTag ?? "")
        { [weak self] list, next in
            guard let self else { return }
            guard let list else {
                tableView.mj_header?.endRefreshing()
                tableView.mj_footer?.endRefreshingWithNoMoreData()
                
                if curList.isEmpty {
                    emptyView.showNetworkError()
                }
                return
            }
            if nextTag?.isEmpty != false {
                curList = list
            } else {
                curList.append(contentsOf: list)
            }
            nextTag = next
            
            tableView.reloadData()
            if curList.isEmpty {
                emptyView.showNoData(tips: .init(key: "A00244"))
            } else {
                emptyView.hide()
            }
            
            self.tableView.mj_header?.endRefreshing()
            if next?.isEmpty != false {
                tableView.mj_footer?.endRefreshingWithNoMoreData()
            } else {
                tableView.mj_footer?.endRefreshing()
            }
        }
    }
    
    func reportExposure() {
        guard tableView.contentOffset.y >= 0 else {
            return
        }
        
        guard let indexs = tableView.indexPathsForVisibleRows,
              !indexs.isEmpty else {
            return
        }
        
        var items: [LNGameMateSearchResultVO] = []
        for index in indexs {
            items.append(curList[index.row])
        }
        
        LNStatisticManager.shared.reportExposure(uids: items.map({ $0.userNo })) { _ in }
    }
}

extension LNUserSearchViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        curList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(
            withIdentifier: LNUserSearchItemCell.className,
            for: indexPath) as! LNUserSearchItemCell
        
        let item = curList[indexPath.row]
        cell.update(item)
        
        return cell
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if searchInput.isFirstResponder {
            view.endEditing(true)
        }
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        reportExposure()
    }
    
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        reportExposure()
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate {
            reportExposure()
        }
    }
}

extension LNUserSearchViewController: LNUserSearchHistoryViewDelegate {
    func onUserSearchHistoryView(view: LNUserSearchHistoryView, didClick history: String) {
        searchInput.text = history
        curKeyword = history
        nextTag = nil
        curList.removeAll()
        tableView.reloadData()
        tableView.mj_header?.beginRefreshing()
    }
}

extension LNUserSearchViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        guard let text = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines),
              !text.isEmpty else { return true }
        
        curKeyword = text
        nextTag = nil
        curList.removeAll()
        tableView.reloadData()
        tableView.mj_header?.beginRefreshing()
        
        return true
    }
}

extension LNUserSearchViewController {
    private func setupViews() {
        setupNavBar()
        
        let history = buildHistory()
        view.addSubview(history)
        history.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview().offset(12)
        }
        
        let list = buildList()
        view.addSubview(list)
        list.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview().offset(12)
            make.bottom.equalToSuperview()
        }
        
        view.onTap { [weak self] in
            guard let self else { return }
            view.endEditing(true)
        }
    }
    
    private func setupNavBar() {
        let search = UIButton()
        search.setTitle(.init(key: "A00245"), for: .normal)
        search.setTitleColor(.text_5, for: .normal)
        search.titleLabel?.font = .heading_h4
        search.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        search.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
        search.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            _ = textFieldShouldReturn(searchInput)
        }), for: .touchUpInside)
        setRightButton(search)
        
        let input = buildSearchInput()
        setTitleView(input)
    }
    
    private func buildSearchInput() -> UIView {
        let container = UIView()
        container.backgroundColor = .fill_2
        container.layer.cornerRadius = 18
        container.snp.makeConstraints { make in
            make.height.equalTo(36)
            make.width.equalTo(view.bounds.width).priority(.medium)
        }
        
        let ic = UIImageView()
        ic.image = .icMagnifyingglass
        container.addSubview(ic)
        ic.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(10)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(18)
        }
        
        searchInput.font = .body_s
        searchInput.placeholder = .init(key: "A00246")
        searchInput.clearButtonMode = .always
        searchInput.returnKeyType = .search
        searchInput.enablesReturnKeyAutomatically = true
        searchInput.delegate = self
        searchInput.becomeFirstResponder()
        searchInput.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            if searchInput.text?.isEmpty != false {
                historyView.isHidden = false
                tableView.isHidden = true
            }
        }), for: .editingChanged)
        container.addSubview(searchInput)
        searchInput.snp.makeConstraints { make in
            make.leading.equalTo(ic.snp.trailing).offset(8)
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-10)
        }
        
        return container
    }
    
    private func buildList() -> UIView {
        let header = MJRefreshNormalHeader { [weak self] in
            guard let self else { return }
            nextTag = nil
            searchUser()
        }
        header.lastUpdatedTimeLabel?.isHidden = true
        header.stateLabel?.isHidden = true
        header.endRefreshingCompletionBlock = { [weak self] in
            guard let self else { return }
            reportExposure()
        }
        tableView.mj_header = header
        
        let footer = MJRefreshAutoNormalFooter { [weak self] in
            guard let self else { return }
            searchUser()
        }
        footer.setTitle("", for: .noMoreData)
        footer.setTitle(.init(key: "A00046"), for: .idle)
        footer.endRefreshingCompletionBlock = { [weak self] in
            guard let self else { return }
            reportExposure()
        }
        
        tableView.mj_footer = footer
        tableView.isHidden = true
        tableView.dataSource = self
        tableView.delegate = self
        tableView.separatorStyle = .none
        tableView.showsVerticalScrollIndicator = false
        tableView.showsHorizontalScrollIndicator = false
        tableView.register(
            LNUserSearchItemCell.self,
            forCellReuseIdentifier: LNUserSearchItemCell.className
        )
        
        tableView.addSubview(emptyView)
        emptyView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview().multipliedBy(0.6)
        }
        
        return tableView
    }
    
    private func buildHistory() -> UIView {
        historyView.isHidden = false
        historyView.delegate = self
        
        return historyView
    }
}

#if DEBUG

import SwiftUI

struct LNIMSearchViewControllerPreview: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> some UIViewController {
        LNUserSearchViewController()
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        
    }
}

#Preview(body: {
    LNIMSearchViewControllerPreview()
})
#endif
