//
//  LNProfileFeedItemCell.swift
//  Gami
//
//  Created by OneeChan on 2026/3/2.
//

import Foundation
import UIKit
import SnapKit
import AVKit


class LNProfileFeedItemCell: UITableViewCell {
    private let avatar = UIImageView()
    private let nameLabel = UILabel()
    private let timeLabel = UILabel()
    
    private let photosView = LNMultiLineStackView()
    private let singlePhotoView = UIImageView()
    
    private var videoView = LNVideoPlayerView()
    private let durationLabel = UILabel()
    private let muteButton = UIButton()
    
    private let contentLabel = UILabel()
    
    private let inputField = UITextField()
    
    private let likeView = LNFeedLikeView()
    private let commentView = LNFeedCommentView()
    
    private var curItem: LNFeedItemVO?
    
    var isVideo: Bool {
        videoView.superview?.isHidden == false
    }
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        setupViews()
        LNEventDeliver.addObserver(self)
    }
    
    func update(_ item: LNFeedItemVO) {
        avatar.sd_setImage(with: URL(string: item.avatar))
        nameLabel.text = item.nickname
        timeLabel.text = TimeInterval(item.createdAt / 1_000).tencentIMTimeDesc
        contentLabel.attributedText = item.textContent.getEmojiString(with: .body_m)
        likeView.update(id: item.id, liked: item.liked, count: item.likeCount)
        commentView.update(id: item.id, count: item.commentCount)
        videoView.stop()
        
        if item.medias.isEmpty { // 无媒体
            photosView.isHidden = true
            singlePhotoView.superview?.isHidden = true
            videoView.superview?.isHidden = true
        } else if let video = item.medias.first(where: { $0.type == .video }) { // 视频消息
            photosView.isHidden = true
            singlePhotoView.superview?.isHidden = true
            
            videoView.superview?.isHidden = false
            videoView.loadVideo(video.url, coverUrl: video.videoCover)
            if LNFeedManager.videoMute {
                videoView.mute()
            } else {
                videoView.unmute()
            }
            let size = video.videoCover.extractSize
            videoView.snp.remakeConstraints { make in
                make.verticalEdges.equalToSuperview()
                if size.width > size.height {
                    // 横屏
                    make.horizontalEdges.equalToSuperview()
                    make.height.equalTo(videoView.snp.width).multipliedBy(167.0/343.0)
                } else {
                    // 竖屏
                    make.leading.equalToSuperview()
                    make.width.equalToSuperview().multipliedBy(0.5)
                    make.height.equalTo(videoView.snp.width).multipliedBy(223.0/167.0)
                }
            }
        } else {
            videoView.superview?.isHidden = true
            
            if item.medias.count == 1 { // 单图
                photosView.isHidden = true
                singlePhotoView.superview?.isHidden = false
                singlePhotoView.sd_setImage(with: URL(string: item.medias[0].url))
                let size = item.medias[0].url.extractSize
                singlePhotoView.snp.remakeConstraints { make in
                    make.leading.equalToSuperview()
                    make.verticalEdges.equalToSuperview()
                    if size.width == size.height {
                        // 正方形
                        make.width.equalToSuperview().multipliedBy(0.5)
                        make.height.equalTo(singlePhotoView.snp.width)
                    } else if size.width > size.height {
                        // 横屏
                        make.width.equalTo(223)
                        make.height.equalTo(167)
                    } else {
                        // 竖屏
                        make.width.equalToSuperview().multipliedBy(0.5)
                        make.height.equalTo(singlePhotoView.snp.width).multipliedBy(223.0/167.0)
                    }
                }
            } else { // 多图
                singlePhotoView.superview?.isHidden = true
                
                photosView.isHidden = false
                if item.medias.map({ $0.url }) != curItem?.medias.map({ $0.url }) {
                    if item.medias.count == 2 {
                        photosView.columns = 2
                    } else {
                        photosView.columns = 3
                    }
                    var itemViews: [UIView] = []
                    for (index, media) in item.medias.enumerated() {
                        let imageView = buildImageView()
                        imageView.sd_setImage(with: URL(string: media.url))
                        imageView.onTap { [weak self] in
                            guard let self else { return }
                            presentImagePreview(item.medias.map({ $0.url }), index)
                        }
                        imageView.snp.makeConstraints { make in
                            make.height.equalTo(imageView.snp.width)
                        }
                        itemViews.append(imageView)
                    }
                    photosView.update(itemViews)
                }
            }
        }
        
        curItem = item
    }
    
    func autoPlayVideoIfNeed() {
        guard videoView.superview?.isHidden == false else { return }
        if videoView.isPlaying { return }
        videoView.start()
    }
    
    func stopPlayVideoIfNeed() {
        guard videoView.superview?.isHidden == false else { return }
        if !videoView.isPlaying { return }
        videoView.stop()
    }
    
    override func didMoveToWindow() {
        super.didMoveToWindow()
        if window == nil {
            stopPlayVideoIfNeed()
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNProfileFeedItemCell {
    private func toComment() {
        guard let curItem else { return }
        let panel = LNCommonInputPanel()
        panel.maxInput = LNFeedManager.feedCommentMaxInput
        panel.handler = { comment in
            LNFeedManager.shared.sendFeedComment(id: curItem.id, content: comment)
            { success in
                guard success else { return }
                curItem.commentCount += 1
                LNFeedManager.shared.notifyFeedCommentChanged(id: curItem.id, count: curItem.commentCount)
            }
        }
        panel.popup()
    }
}

extension LNProfileFeedItemCell: LNVideoPlayerViewDelegate {
    func onVideoProgressChanged(view: LNVideoPlayerView, cur: Float64, total: Float64) {
        let remain = total - cur
        durationLabel.text = TimeInterval(remain).timeCountDisplay
    }
    
    func onVideoDidStop(view: LNVideoPlayerView) {
        durationLabel.text = view.duration.timeCountDisplay
    }
    
    func onVideoDidLoad(view: LNVideoPlayerView) {
        durationLabel.text = videoView.duration.timeCountDisplay
    }
    
    func onVideoMutedChanged(view: LNVideoPlayerView) {
        if videoView.isMuted {
            muteButton.setImage(.icVideoVolumnMute.withTintColor(.white), for: .normal)
        } else {
            muteButton.setImage(.icVideoVolumnNormal.withTintColor(.white), for: .normal)
        }
    }
}

extension LNProfileFeedItemCell {
    private func setupViews() {
        let container = UIView()
        container.onTap { [weak self] in
            guard let self else { return }
            guard let curItem else { return }
            if curItem.medias.first(where: { $0.type == .video }) != nil {
                pushToVideoFeedDetail(id: curItem.id)
            } else {
                pushToImageFeedDetail(id: curItem.id)
            }
        }
        contentView.addSubview(container)
        container.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview()
            make.bottom.equalToSuperview().priority(.low)
        }
        
        let userInfo = buildUserInfo()
        container.addSubview(userInfo)
        userInfo.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview().offset(12)
        }
        
        let mediaView = buildMeiaView()
        container.addSubview(mediaView)
        mediaView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(userInfo.snp.bottom).offset(8)
        }
        
        let content = buildTextContent()
        container.addSubview(content)
        content.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(mediaView.snp.bottom).offset(5)
        }
        
        let menu = buildMenuView()
        container.addSubview(menu)
        menu.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(content.snp.bottom).offset(18)
        }
        
        let line = UIView()
        line.backgroundColor = .primary_1
        container.addSubview(line)
        line.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(menu.snp.bottom).offset(16)
            make.bottom.equalToSuperview().offset(-4)
            make.height.equalTo(1)
        }
    }
    
    private func buildUserInfo() -> UIView {
        let container = UIView()
        container.snp.makeConstraints { make in
            make.height.equalTo(35)
        }
        
        avatar.layer.cornerRadius = 16
        avatar.clipsToBounds = true
        container.addSubview(avatar)
        avatar.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.centerY.equalToSuperview()
            make.width.height.equalTo(32)
        }
        
        let textContainer = UIView()
        container.addSubview(textContainer)
        textContainer.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview()
            make.leading.equalTo(avatar.snp.trailing).offset(10)
        }
        
        nameLabel.text = " "
        nameLabel.font = .heading_h4
        nameLabel.textColor = .text_5
        textContainer.addSubview(nameLabel)
        nameLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        timeLabel.text = " "
        timeLabel.font = .body_xs
        timeLabel.textColor = .text_3
        textContainer.addSubview(timeLabel)
        timeLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.bottom.equalToSuperview()
            make.top.equalTo(nameLabel.snp.bottom).offset(4)
        }
        
        return container
    }
    
    private func buildMeiaView() -> UIView {
        let stackView = UIStackView()
        stackView.axis = .vertical
        
        photosView.isHidden = true
        photosView.columns = 2
        photosView.spacing = 6
        photosView.itemSpacing = 6
        photosView.itemDistribution = .fillEqually
        stackView.addArrangedSubview(photosView)
        
        let singleView = UIView()
        singleView.isHidden = true
        stackView.addArrangedSubview(singleView)
        
        singlePhotoView.layer.cornerRadius = 12
        singlePhotoView.clipsToBounds = true
        singlePhotoView.contentMode = .scaleAspectFill
        singlePhotoView.onTap { [weak self] in
            guard let self else { return }
            guard let curItem else { return }
            presentImagePreview(curItem.medias.filter({ $0.type == .image }).map({ $0.url }), 0)
        }
        singleView.addSubview(singlePhotoView)
        singlePhotoView.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.leading.equalToSuperview()
            make.width.height.equalTo(0)
        }
        
        stackView.addArrangedSubview(buildVideo())
        
        return stackView
    }
    
    private func buildVideo() -> UIView {
        let container = UIView()
        container.isHidden = true
        
        videoView.layer.cornerRadius = 12
        videoView.clipsToBounds = true
        videoView.delegate = self
        videoView.loop = true
        videoView.isUserInteractionEnabled = false
        videoView.setScaleMode(.resizeAspectFill)
        container.addSubview(videoView)
        videoView.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.verticalEdges.equalToSuperview()
            make.width.height.equalTo(0)
        }
        
        let bottomView = UIView()
        container.addSubview(bottomView)
        bottomView.snp.makeConstraints { make in
            make.height.equalTo(36)
            make.horizontalEdges.equalTo(videoView)
            make.bottom.equalTo(videoView)
        }
        
        durationLabel.font = .body_m
        durationLabel.textColor = .text_1
        bottomView.addSubview(durationLabel)
        durationLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(14)
            make.centerY.equalToSuperview()
        }
        
        muteButton.setImage(.icVideoVolumnNormal.withTintColor(.white), for: .normal)
        muteButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            if videoView.isMuted {
                videoView.unmute()
                LNFeedManager.videoMute = false
            } else {
                videoView.mute()
                LNFeedManager.videoMute = true
            }
        }), for: .touchUpInside)
        bottomView.addSubview(muteButton)
        muteButton.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-14)
            make.centerY.equalToSuperview()
        }
        
        return container
    }
    
    private func buildTextContent() -> UIView {
        contentLabel.font = .body_m
        contentLabel.textColor = .text_5
        contentLabel.numberOfLines = 0
        
        return contentLabel
    }
    
    private func buildMenuView() -> UIView {
        let container = UIView()
        container.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        
        let comment = buildComment()
        container.addSubview(comment)
        comment.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        let like = buildLike()
        container.addSubview(like)
        like.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(comment.snp.leading).offset(-20)
        }
        
        let input = buildInput()
        container.addSubview(input)
        input.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalToSuperview()
            make.width.equalTo(165)
        }
        
        return container
    }
    
    private func buildComment() -> UIView {
        commentView.uiColor = .text_4
        
        return commentView
    }
    
    private func buildLike() -> UIView {
        likeView.uiColor = .text_4
        
        return likeView
    }
    
    private func buildInput() -> UIView {
        let container = UIView()
        container.backgroundColor = .fill_2
        container.layer.cornerRadius = 15
        container.onTap { [weak self] in
            guard let self else { return }
            toComment()
        }
        container.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        
        let editIc = UIImageView()
        editIc.image = .icImChatMenuRemark.withTintColor(.text_2)
        container.addSubview(editIc)
        editIc.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(10)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(22)
        }
        
        let tipsLabel = UILabel()
        tipsLabel.font = .body_xs
        tipsLabel.textColor = .text_2
        tipsLabel.text = .init(key: "A00300")
        container.addSubview(tipsLabel)
        tipsLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(editIc.snp.trailing).offset(4)
            make.trailing.equalToSuperview().offset(-10)
        }
        
        return container
    }
    
    private func buildImageView() -> UIImageView {
        let imageView = UIImageView()
        imageView.layer.cornerRadius = 12
        imageView.clipsToBounds = true
        imageView.contentMode = .scaleAspectFill
        
        return imageView
    }
}

#if DEBUG

import SwiftUI

struct LNProfileFeedItemCellPreview: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        let container = UIView()
        container.backgroundColor = .lightGray
        
        let view = LNProfileFeedItemCell()
        container.addSubview(view)
        view.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.centerY.equalToSuperview()
            make.height.equalTo(72)
        }
        
        return container
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) { }
}

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

