//
//  LNLoginPanel.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/2.
//

import Foundation
import UIKit
import SnapKit


private weak var curLoginPanel: LNLoginPanel? = nil


class LNLoginPanel: LNPopupView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        containerHeight = .percent(1.0)
        
        setupViews()
        
        LNEventDeliver.addObserver(self)
    }
    
    static func show(container: UIView?) {
        guard curLoginPanel == nil else { return }
            
        let panel = LNLoginPanel()
        panel.popup(container)
        curLoginPanel = panel
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNLoginPanel: LNAccountManagerNotify {
    func onUserLogin() {
        dismiss()
    }
}

extension LNLoginPanel {
    private func setupViews() {
        container.backgroundColor = .text_5.withAlphaComponent(0.7)
        
        let logo = UIImageView()
        logo.image = .icLoginLogo
        container.addSubview(logo)
        logo.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview().multipliedBy(0.5)
        }
        
        let privacy = buildPrivacy()
        container.addSubview(privacy)
        privacy.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.width.equalToSuperview().offset(-50)
            make.bottom.equalToSuperview().offset(-safeBottomInset - 40)
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 16
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(38)
            make.bottom.equalTo(privacy.snp.top).offset(-50)
        }
        
#if DEBUG
        let email = buildEmail()
        stackView.addArrangedSubview(email)
#endif
        let phone = buildLoginItem(icon: .icLoginPhone, title: .init(key: "B00019"), textColor: .text_1, color: .primary_3)
        phone.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            pushToLoginPhone()
        }), for: .touchUpInside)
        stackView.addArrangedSubview(phone)
        
        let apple = buildLoginItem(icon: .icApple, title: .init(key: "A00285"), textColor: .text_1, color: .init(hex: "#0B0B0A"))
        apple.addAction(UIAction(handler: { [weak self] _ in
            guard self != nil else { return }
            LNAccountManager.shared.doAppleLogin()
        }), for: .touchUpInside)
        stackView.addArrangedSubview(apple)
        
        let google = buildLoginItem(icon: .icGoogle, title: .init(key: "A00115"), textColor: .text_5, color: .fill)
        google.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let topVC = navigationController?.topViewController else { return }
            LNAccountManager.shared.doGoogleLogin(topVC)
        }), for: .touchUpInside)
        stackView.addArrangedSubview(google)
        
        let tipsLabel = UILabel()
        tipsLabel.text = .init(key: "A00114")
        tipsLabel.font = .body_m
        tipsLabel.textColor = .primary_3
        tipsLabel.numberOfLines = 0
        tipsLabel.textAlignment = .center
        container.addSubview(tipsLabel)
        tipsLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(38)
            make.bottom.equalTo(stackView.snp.top).offset(-16)
        }
        
        let close = buildClose()
        container.addSubview(close)
        close.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(UIView.statusBarHeight)
            make.trailing.equalToSuperview().offset(-20)
        }
    }
    
    private func buildLoginItem(icon: UIImage, title: String, textColor: UIColor, color: UIColor) -> UIButton {
        let button = UIButton()
        button.setBackgroundImage(UIImage.image(for: color), for: .normal)
        button.layer.cornerRadius = 24
        button.clipsToBounds = true
        button.snp.makeConstraints { make in
            make.height.equalTo(48)
        }
        
        let ic = UIImageView()
        ic.image = icon
        button.addSubview(ic)
        ic.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalToSuperview().offset(12)
        }
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h3
        titleLabel.textColor = textColor
        titleLabel.text = title
        button.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        return button
    }
    
    private func buildPrivacy() -> UIView {
        let text: String = .init(key: "A00116")
        let attrStr = NSMutableAttributedString(string: text)
        let agreementRange = (text.lowercased() as NSString).range(of: .init(key: "A00117").lowercased())
        attrStr.addAttributes([
            .link: String.serviceUrl,
            .underlineStyle: NSUnderlineStyle.single.rawValue,
            .underlineColor: UIColor.text_2
        ], range: agreementRange)
        
        let privacyRange = (text.lowercased() as NSString).range(of: .init(key: "A00118").lowercased())
        attrStr.addAttributes([
            .link: String.privacyUrl,
            .underlineStyle: NSUnderlineStyle.single.rawValue,
            .underlineColor: UIColor.text_2,
        ], range: privacyRange)
        
        let privacyView = LNPrivacyTextView()
        privacyView.attributedText = attrStr
        privacyView.textAlignment = .center
        privacyView.backgroundColor = .clear
        privacyView.font = .systemFont(ofSize: 13.4)
        privacyView.textColor = .text_2
        privacyView.linkTextAttributes = [.foregroundColor: UIColor.text_1]
        
        return privacyView
    }
    
#if DEBUG
    private func buildEmail() -> UIView {
        let container = UIView()
        container.backgroundColor = .fill
        container.layer.cornerRadius = 24
        container.snp.makeConstraints { make in
            make.height.equalTo(48)
        }
        
        let input = UITextField()
        let login = UIButton()
        login.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        login.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
        login.setImage(.init(systemName: "arrow.forward"), for: .normal)
        login.addAction(UIAction(handler: { [weak self] _ in
            guard self != nil else { return }
            guard let text = input.text, !text.isEmpty else { return }
            LNAccountManager.shared.loginByEmail(email: text) { _ in }
        }), for: .touchUpInside)
        container.addSubview(login)
        login.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-16)
        }
        
        container.addSubview(input)
        input.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.leading.equalToSuperview().offset(16)
            make.trailing.equalTo(login.snp.leading)
        }
        
        return container
    }
#endif
    
    private func buildClose() -> UIView {
        let config = UIImage.SymbolConfiguration(pointSize: 24)
        
        let button = UIButton()
        button.setImage(.init(systemName: "xmark", withConfiguration: config), for: .normal)
        button.tintColor = .white
        button.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            self.dismiss()
        }), for: .touchUpInside)
        
        return button
    }
}


#if DEBUG

import SwiftUI
import AuthenticationServices

struct LNLoginPanelPreview: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        let container = UIView()
        container.backgroundColor = .lightGray
        
        let view = LNLoginPanel()
        view.popup(container)
        
        return container
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) { }
}

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

