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

import Foundation
import UIKit
import SnapKit


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

enum LNUserSearchTab: Int, CaseIterable {
    case overview
    case user
    case rooms
    
    var title: String {
        switch self {
        case .overview:
            .init(key: "A00363")
        case .user:
            .init(key: "A00364")
        case .rooms:
            .init(key: "A00365")
        }
    }
}

class LNUserSearchViewController: LNViewController {
    private let searchInput = UITextField()
    
    private let historyView = LNUserSearchHistoryView()
    
    private let searchView = UIView()
    private let scrollView = UIScrollView()
    private let tabsView = LNUserSearchTabsView()
    private let overviewListView = LNUserSearchOverviewListView()
    private let userListView = LNUserSearchUserListView()
    private let roomListView = LNUserSearchRoomListView()
    private lazy var resultViews = [overviewListView, userListView, roomListView]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupViews()
        showLandingState()
    }
}

extension LNUserSearchViewController: UIScrollViewDelegate {
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        syncTabFromPageScroll()
    }
    
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        syncTabFromPageScroll()
    }
}

extension LNUserSearchViewController: LNUserSearchHistoryViewDelegate {
    func onUserSearchHistoryView(view: LNUserSearchHistoryView, didClick history: String) {
        searchInput.text = history
        triggerSearchIfNeeded()
    }
}

extension LNUserSearchViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        triggerSearchIfNeeded()
        return true
    }
}

extension LNUserSearchViewController: LNUserSearchOverviewListViewDelegate {
    func onUserSearchOverviewListView(view: LNUserSearchOverviewListView, didClickMore tab: LNUserSearchTab) {
        selectTab(tab, animated: true)
    }
}

extension LNUserSearchViewController {
    private func triggerSearchIfNeeded() {
        searchInput.resignFirstResponder()
        
        let keyword = searchInput.text?
            .trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        if keyword.isEmpty {
            showLandingState()
            return
        }
        
        searchInput.text = keyword
        historyView.addRecord(keyword)
        
        overviewListView.search(keyword)
        userListView.search(keyword: keyword)
        roomListView.search(keyword: keyword)
        
        searchView.isHidden = false
        historyView.isHidden = true
        
        userListView.search(keyword: keyword)
        selectTab(.overview, animated: false)
    }
    
    private func showLandingState() {
        searchView.isHidden = true
        historyView.isHidden = false
    }
    
    private func selectTab(_ tab: LNUserSearchTab, animated: Bool) {
        tabsView.update(selected: tab, animated: animated)
        
        guard scrollView.bounds.width > 0 else {
            return
        }
        
        let offsetX: CGFloat = scrollView.bounds.width * CGFloat(tab.rawValue)
        scrollView.setContentOffset(.init(x: offsetX, y: 0), animated: animated)
        if !animated {
            syncTabFromPageScroll()
        }
    }
    
    private func syncTabFromPageScroll() {
        guard scrollView.bounds.width > 0 else { return }
        let page = Int(round(scrollView.contentOffset.x / scrollView.bounds.width))
        guard let tab = LNUserSearchTab(rawValue: max(0, min(page, LNUserSearchTab.allCases.count - 1))) else { return }
        tabsView.update(selected: tab, animated: true)
    }
}

extension LNUserSearchViewController {
    private func setupViews() {
        setupNavBar()
        
        historyView.delegate = self
        view.addSubview(historyView)
        historyView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        let resultView = buildResultView()
        view.addSubview(resultView)
        resultView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        view.onTap { [weak self] in
            self?.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
            self?.triggerSearchIfNeeded()
        }), 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 icon = UIImageView()
        icon.image = .icMagnifyingglass
        container.addSubview(icon)
        icon.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(10)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(18)
        }
        
        searchInput.font = .body_s
        searchInput.textColor = .text_5
        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 {
                showLandingState()
            }
        }), for: .editingChanged)
        container.addSubview(searchInput)
        searchInput.snp.makeConstraints { make in
            make.leading.equalTo(icon.snp.trailing).offset(8)
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-10)
        }
        
        return container
    }
    
    private func buildResultView() -> UIView {
        tabsView.onSelect = { [weak self] tab in
            self?.selectTab(tab, animated: true)
        }
        searchView.addSubview(tabsView)
        tabsView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        scrollView.isPagingEnabled = true
        scrollView.delegate = self
        searchView.addSubview(scrollView)
        scrollView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.bottom.equalToSuperview()
            make.top.equalTo(tabsView.snp.bottom)
        }
        
        let stackView = UIStackView()
        scrollView.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.height.equalToSuperview()
        }
        
        overviewListView.delegate = self
        for view in resultViews {
            stackView.addArrangedSubview(view)
            view.snp.makeConstraints { make in
                make.width.height.equalTo(scrollView)
            }
        }
        
        return searchView
    }
}

#if DEBUG

import SwiftUI

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

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