//
//  LNEditProfileViewController.swift
//  Lanu
//
//  Created by OneeChan on 2025/11/26.
//

import Foundation
import UIKit
import SnapKit


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


class LNEditProfileViewController: LNViewController {
    private let saveButton = UIButton()
    
    private let profilePhoto = LNImageUploadView()
    private var curProfilePhoto = "" {
        didSet {
            profilePhoto.loadImage(url: curProfilePhoto)
        }
    }
    
    private let photoWall = LNEditProfilePhotoWallView()
    
    private let nameLabel = UILabel()
    private var curName = "" {
        didSet {
            nameLabel.text = curName
        }
    }
    
    private let genderLabel = UILabel()
    private var curGender: LNUserGender = .unknow {
        didSet {
            genderLabel.text = curGender.desc
        }
    }
    
    private let birthdayLabel = UILabel()
    private var curBirthday: Double = 0 {
        didSet {
            birthdayLabel.text = curBirthday.formattedFullDate("-")
        }
    }
    
    private let bioLabel = UILabel()
    private var curBio = "" {
        didSet {
            if curBio.isEmpty {
                bioLabel.text = nil
                bioLabel.attributedText = .init(string: .init(key: "A00200"), attributes: [.foregroundColor: UIColor.text_6])
            } else {
                bioLabel.attributedText = nil
                bioLabel.text = curBio
            }
        }
    }
    
    private let interestLabel = UILabel()
    private var curInterest: [LNUserInterestVO] = [] {
        didSet {
            if curInterest.isEmpty {
                interestLabel.text = nil
                interestLabel.attributedText = .init(string: .init(key: "A00201"), attributes: [.foregroundColor: UIColor.text_6])
            } else {
                interestLabel.attributedText = nil
                interestLabel.text = curInterest.map({ $0.name }).joined(separator: ", ")
            }
        }
    }
    private let voiceLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupViews()
        
        loadUserInfo()
        
        checkSaveButton()
        
        LNEventDeliver.addObserver(self)
    }
}

extension LNEditProfileViewController {
    private func loadUserInfo() {
        curBio = myUserInfo.intro
        curInterest = myUserInfo.interests
        curProfilePhoto = myUserInfo.avatar
        curName = myUserInfo.nickname
        curGender =  myUserInfo.gender
        curBirthday = Double(myUserInfo.birthday / 1_000)
        
        updateVoiceText()
    }
}

extension LNEditProfileViewController: LNProfileManagerNotify {
    func onUserVoiceBarInfoChanged() {
        updateVoiceText()
    }
    
    func onUserInfoChanged(userInfo: LNUserProfileVO) {
        guard userInfo.userNo.isMyUid else { return }
        
        updateVoiceText()
    }
    
    private func updateVoiceText() {
        if myVoiceBarInfo.status == .done {
            voiceLabel.attributedText = nil
            voiceLabel.text = .init(key: "B00002")
        } else if myVoiceBarInfo.status == .review {
            voiceLabel.attributedText = nil
            voiceLabel.text =  .init(key: "B00003")
        } else if myUserInfo.voiceBar.isEmpty {
            voiceLabel.text = nil
            voiceLabel.attributedText = .init(string: .init(key: "B00001"), attributes: [.foregroundColor: UIColor.text_6])
        }
    }
}

extension LNEditProfileViewController: LNImageUploadViewDelegate {
    func onImageUploadView(view: LNImageUploadView, didUploadImage url: String) {
        checkSaveButton()
    }
    
    func onImageUploadViewDidClickDelete(view: LNImageUploadView) {
        checkSaveButton()
    }
}

extension LNEditProfileViewController: LNEditProfilePhotoWallViewDelegate {
    func onEditProfilePhotoWallViewDidChanged(view: LNEditProfilePhotoWallView) {
        checkSaveButton()
    }
}

extension LNEditProfileViewController {
    private func checkSaveButton() {
        let enable = profilePhoto.imageUrl != myUserInfo.avatar
        || photoWall.curPhotos != myUserInfo.photos
        || curName != myUserInfo.nickname
        || curGender != myUserInfo.gender
        || curBirthday != Double(myUserInfo.birthday / 1_000)
        || curBio != myUserInfo.intro
        || curInterest.map({ $0.code }) != myUserInfo.interests.map({ $0.code })
        
        if enable, !saveButton.isEnabled {
            saveButton.isEnabled = true
            saveButton.setBackgroundImage(.primary_8, for: .normal)
        } else if !enable, saveButton.isEnabled {
            saveButton.isEnabled = false
            saveButton.setBackgroundImage(nil, for: .normal)
        }
    }
    
    private func setupViews() {
        setupNavBar()
        
        let scrollView = UIScrollView()
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.clipsToBounds = false
        scrollView.contentInset = .init(top: 0, left: 0, bottom: -view.commonBottomInset, right: 0)
        view.addSubview(scrollView)
        scrollView.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.horizontalEdges.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 24
        scrollView.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.horizontalEdges.equalToSuperview().inset(16)
            make.width.equalToSuperview().offset(-32)
        }
        
        stackView.addArrangedSubview(buildProfilePhoto())
        stackView.addArrangedSubview(buildPhotoWall())
        stackView.addArrangedSubview(buildUserInfo())
        stackView.addArrangedSubview(buildSkillInfo())
    }
    
    private func setupNavBar() {
        customBack = { [weak self] in
            guard let self else { return }
            if saveButton.isEnabled {
                LNCommonAlertView.showProfileEditEnsaveAlert { [weak self] in
                    guard let self else { return }
                    navigationController?.popViewController(animated: true)
                }
            } else {
                navigationController?.popViewController(animated: true)
            }
        }
        title = .init(key: "A00202")
        
        saveButton.backgroundColor = .fill_4
        saveButton.layer.cornerRadius = 16
        saveButton.setBackgroundImage(.primary_8, for: .normal)
        saveButton.clipsToBounds = true
        saveButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            let config = LNProfileUpdateConfig()
            if profilePhoto.imageUrl != myUserInfo.avatar {
                config.avatar = profilePhoto.imageUrl
            }
            let photos = photoWall.curPhotos
            if photos != myUserInfo.photos {
                config.photos = photos
            }
            if curName != myUserInfo.nickname {
                config.nickName = curName
            }
            if curGender != myUserInfo.gender {
                config.gender = curGender
            }
            if curBirthday != Double(myUserInfo.birthday / 1_000) {
                config.birthday = curBirthday.formattedFullDate("-", normal: true)
            }
            if curBio != myUserInfo.intro {
                config.bio = curBio
            }
            if curInterest.map({ $0.code }) != myUserInfo.interests.map({ $0.code }) {
                config.interest = curInterest.map({ $0.code })
            }
            LNProfileManager.shared.modifyMyProfile(config: config) { [weak self] success in
                guard let self else { return }
                guard success else { return }
                navigationController?.popViewController(animated: true)
            }
        }), for: .touchUpInside)
        setRightButton(saveButton)
        saveButton.snp.makeConstraints { make in
            make.height.equalTo(32)
        }
        
        let saveLabel = UILabel()
        saveLabel.text = .init(key: "A00185")
        saveLabel.font = .heading_h4
        saveLabel.textColor = .text_1
        saveButton.addSubview(saveLabel)
        saveLabel.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.equalToSuperview().offset(17)
        }
    }
    
    private func buildProfilePhoto() -> UIView {
        let container = UIView()
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h4
        titleLabel.textColor = .text_5
        titleLabel.text = .init(key: "A00203")
        container.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview().offset(10)
        }
        
        profilePhoto.uploadType = .avatar
        profilePhoto.backgroundColor = .fill_2
        profilePhoto.layer.cornerRadius = 11
        profilePhoto.clipsToBounds = true
        profilePhoto.contentMode = .scaleAspectFill
        profilePhoto.showClearButton = false
        profilePhoto.showDefault = true
        profilePhoto.delegate = self
        profilePhoto.onTap { [weak self] in
            guard let self else { return }
            LNBottomSheetMenu.showImageSelectMenu(view: view, options: .init(allowEdit: true))
            { [weak self] image, _ in
                guard let self else { return }
                guard let image = image?.compress(type: .avatar) else { return }
                profilePhoto.uploadImage(image: image)
            }
        }
        container.addSubview(profilePhoto)
        profilePhoto.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.top.equalTo(titleLabel.snp.bottom).offset(10)
            make.bottom.equalToSuperview()
            make.height.width.equalTo(110)
        }
        
        return container
    }
    
    private func buildPhotoWall() -> UIView {
        photoWall.delegate = self
        photoWall.loadImages(myUserInfo.photos)
        
        return photoWall
    }
    
    private func buildUserInfo() -> UIView {
        let container = UIView()
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h4
        titleLabel.textColor = .text_5
        titleLabel.text = .init(key: "A00204")
        container.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview().offset(10)
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 22
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(titleLabel.snp.bottom).offset(10)
            make.bottom.equalToSuperview()
        }
        
        let nameView = buildInfoLine(title: .init(key: "A00188"), label: nameLabel)
        nameView.onTap { [weak self] in
            guard let self else { return }
            let panel = LNEditNickNamePanel()
            panel.inputField.text = curName
            panel.handler = { [weak self] name in
                guard let self else { return }
                curName = name
                checkSaveButton()
            }
            panel.popup()
        }
        stackView.addArrangedSubview(nameView)
        
        let genderView = buildInfoLine(title: .init(key: "A00032"), label: genderLabel)
        genderView.onTap { [weak self] in
            guard let self else { return }
            let panel = LNEditGenderPanel()
            panel.curGender = curGender
            panel.handler = { [weak self] gender in
                guard let self else { return }
                curGender = gender
                checkSaveButton()
            }
            panel.popup()
        }
        stackView.addArrangedSubview(genderView)
        
        let birthdayView = buildInfoLine(title: .init(key: "A00205"), label: birthdayLabel)
        birthdayView.onTap { [weak self] in
            guard let self else { return }
            let panel = LNDatePickerPanel()
            panel.titleLabel.text = .init(key: "A00007")
            panel.datePicker.maximumDate = Date().yearAgo(-18)
            panel.setDefault(curBirthday)
            panel.handler = { [weak self] date in
                guard let self else { return }
                curBirthday = date
                checkSaveButton()
            }
            panel.popup()
        }
        stackView.addArrangedSubview(birthdayView)
        
        let bioView = buildInfoLine(title: .init(key: "A00184"), label: bioLabel)
        bioView.onTap { [weak self] in
            guard let self else { return }
            let panel = LNEditBioPanel()
            panel.update(curBio)
            panel.handler = { [weak self] bio in
                guard let self else { return }
                curBio = bio
                checkSaveButton()
            }
            panel.popup()
        }
        stackView.addArrangedSubview(bioView)
        
        let interestView = buildInfoLine(title: .init(key: "A00206"), label: interestLabel)
        interestView.onTap { [weak self] in
            guard let self else { return }
            let panel = LNEditInterestPanel(selecteds: curInterest.map({ $0.code }))
            panel.handler = { [weak self] items in
                guard let self else { return }
                curInterest = items.map({
                    LNUserInterestVO(code: $0.code, name: $0.name)
                })
                checkSaveButton()
            }
            panel.popup()
        }
        stackView.addArrangedSubview(interestView)
        
        let line = buildLine()
        container.addSubview(line)
        line.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview()
        }
        
        return container
    }
    
    private func buildSkillInfo() -> UIView {
        let container = UIView()
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h4
        titleLabel.textColor = .text_5
        titleLabel.text = .init(key: "B00004")
        container.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview().offset(10)
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 22
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(titleLabel.snp.bottom).offset(10)
            make.bottom.equalToSuperview()
        }
        
        let voiceView = buildInfoLine(title: .init(key: "B00005"), label: voiceLabel)
        voiceView.onTap { [weak self] in
            guard let self else { return }
            let panel = LNEditVoicePanel()
            panel.popup()
        }
        stackView.addArrangedSubview(voiceView)
        
        return container
    }
    
    private func buildInfoLine(title: String, label: UILabel) -> UIView {
        let container = UIView()
        
        let titleLabel = UILabel()
        titleLabel.text = title
        titleLabel.font = .body_m
        titleLabel.textColor = .text_4
        titleLabel.setContentHuggingPriority(.required, for: .horizontal)
        titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
        container.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.leading.equalToSuperview()
        }
        
        let arrow = UIImageView.arrowImageView(size: 14)
        arrow.tintColor = .text_4
        container.addSubview(arrow)
        arrow.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        label.font = .body_m
        label.textColor = .text_3
        container.addSubview(label)
        label.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(arrow.snp.leading).offset(-5)
            make.leading.greaterThanOrEqualTo(titleLabel.snp.trailing).offset(50)
        }
        
        return container
    }
    
    private func buildLine() -> UIView {
        let line = UIView()
        line.backgroundColor = .fill_2
        line.snp.makeConstraints { make in
            make.height.equalTo(1)
        }
        
        return line
    }
}


#if DEBUG

import SwiftUI

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

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