package com.gh.gamecenter.feature.entity

import android.os.Parcel
import android.os.Parcelable
import androidx.room.*
import com.therouter.TheRouter
import com.gh.gamecenter.common.annotation.SyncIgnore
import com.gh.gamecenter.common.annotation.SyncPage
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.core.provider.IUserManagerProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.feature.entity.*
import com.gh.gamecenter.feature.room.converter.*
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parceler
import kotlinx.parcelize.Parcelize

@Entity
@Parcelize
data class ArticleEntity(
    @PrimaryKey
    @SerializedName("_id")
    @ColumnInfo(name = "id")
    private var _id: String = "",
    @SerializedName("title")
    @ColumnInfo(name = "title")
    private var _title: String = "",
    @SerializedName("brief")
    @ColumnInfo(name = "brief")
    private var _brief: String = "",
    @SerializedName("active")
    @ColumnInfo(name = "active")
    private var _active: Boolean = true,
    var orderTag: Long = 0,
    @TypeConverters(ListStringConverter::class)
    @SerializedName("images")
    @ColumnInfo(name = "images")
    private var _images: List<String> = ArrayList(),
    @TypeConverters(ImageInfoConverter::class)
    @SerializedName("images_info")
    var imagesInfo: List<ImageInfo> = ArrayList(),
    @TypeConverters(CommunityVideoConverter::class)
    var videos: List<CommunityVideoEntity> = ArrayList(),
    @SerializedName("count")
    @ColumnInfo(name = "count")
    private var _count: Count = Count(),
    @SerializedName("community", alternate = ["bbs"])
    @ColumnInfo(name = "community")
    private var _community: CommunityEntity = CommunityEntity(),
    var time: TimeEntity? = TimeEntity(),
    @SerializedName("user")
    @ColumnInfo(name = "user")
    private var _user: UserEntity = UserEntity(),
    @Ignore
    var read: Boolean = true,
    @Ignore
    @SerializedName("me")
    @ColumnInfo(name = "me")
    private var _me: MeEntity = MeEntity(),
    @Ignore
    @SerializedName("commentable")
    @ColumnInfo(name = "commentable")
    private var _commentable: Boolean = true,
    var des: String = "",
    var url: String = "",
    @TypeConverters(VideoInfoConverter::class)
    @SerializedName("video_info")
    var videoInfo: VideoInfo = VideoInfo(),
    var poster: String = "",
    var length: Long = 0,
    @SerializedName("type")
    @ColumnInfo(name = "type")
    private var _type: String = "",
    @SerializedName("status")
    @ColumnInfo(name = "status")
    private var _status: String = "",
    var content: String = "",
    @SyncIgnore // questions里的vote当前entity的vote冲突
    @TypeConverters(QuestionsConverter::class)
    @SerializedName("question")
    @ColumnInfo(name = "questions")
    private var _questions: Questions = Questions(),
    @Ignore
    @SerializedName("recommend_id")
    var recommendId: String = "",
    @SerializedName("tag_activity_name")
    @ColumnInfo(name = "tagActivityName")
    private var _tagActivityName: String = "",
    @SerializedName("sections")
    @ColumnInfo(name = "sections")
    @TypeConverters(SectionConverter::class)
    private var _sections: List<SectionEntity> = ArrayList(),
) : Parcelable, CommunityItemData {

    override var id: String
        get() = _id
        set(value) {
            _id = value
        }

    override var type: String
        get() = _type
        set(value) {
            _type = value
        }

    override var active: Boolean
        get() = _active
        set(value) {
            _active = value
        }

    override var commentable: Boolean
        get() = _commentable
        set(value) {
            _commentable = value
        }

    override var me: MeEntity
        get() = _me
        set(value) {
            _me = value
        }

    override var count: Count
        get() = _count
        set(value) {
            _count = value
        }

    override var community: CommunityEntity
        get() = _community
        set(value) {
            _community = value
        }

    override var title: String
        get() = _title
        set(value) {
            _title = value
        }

    override var brief: String
        get() = _brief
        set(value) {
            _brief = value
        }

    override var images: List<String>
        get() = _images
        set(value) {
            _images = value
        }

    override var user: UserEntity
        get() = _user
        set(value) {
            _user = value
        }

    override var status: String
        get() = _status
        set(value) {
            _status = value
        }

    override var questions: Questions
        get() = _questions
        set(value) {
            _questions = value
        }

    override var tagActivityName: String
        get() = _tagActivityName
        set(value) {
            _tagActivityName = value
        }

    override var sections: List<SectionEntity>
        get() = _sections
        set(value) {
            _sections = value
        }

    override var communityId: String?
        get() = community.id
        set(_) {}

    override var communityName: String?
        get() = community.name
        set(_) {}

    fun getPassVideos(): List<CommunityVideoEntity> {
        val passVideos = arrayListOf<CommunityVideoEntity>()
        for (video in videos) {
            if (video.status == "pass") passVideos.add(video)
        }
        return passVideos
    }

    fun transformAnswerEntity(): AnswerEntity {
        if (type != "answer") {
            questions = Questions(title = title, description = brief)
        }
        val answer = AnswerEntity()
        answer.id = id
        answer.title = title
        answer.questions = questions
        answer.brief = brief
        answer.images = images
        answer.videos = videos
        answer.user = user
        if (type.contains("video")) {
            answer.time = time?.upload
        } else {
            answer.time = time?.create
        }
        answer.vote = count.vote
        answer.active = active
        answer.commentCount = count.comment
        answer.answerCount = count.answer
        answer.orderTag = orderTag
        answer.read = read
        answer.me = me
        answer.commentable = commentable
        answer.communityId = community.id
        answer.communityName = community.name
        answer.bbs = community
        answer.type = type
        answer.imagesInfo = imagesInfo
        answer.des = des
        answer.url = url
        answer.videoInfo = videoInfo
        answer.poster = poster
        answer.length = length
        answer.count = count
        answer.status = status
        answer.content = content
        answer.type = type
        answer.sections = sections
        answer.tagActivityName = tagActivityName
        return answer
    }

    fun transformForumVideoEntity(): ForumVideoEntity {
        val forumVideoEntity = ForumVideoEntity()
        if (type.contains("video")) {
            forumVideoEntity.id = id ?: ""
            forumVideoEntity.title = title
            forumVideoEntity.des = des
            forumVideoEntity.url = url
            forumVideoEntity.status = status
            forumVideoEntity.poster = poster
            forumVideoEntity.length = length
            forumVideoEntity.duration = TimeUtils.formatVideoDuration(length)
            forumVideoEntity.videoInfo = videoInfo
            forumVideoEntity.videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
        } else {
            forumVideoEntity.title = title ?: ""
            forumVideoEntity.des = brief ?: ""
            forumVideoEntity.videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
            val userManagerProvider = TheRouter.get(IUserManagerProvider::class.java)
            val newVideos = if (user.id == userManagerProvider?.getUserId()) videos else getPassVideos()
            if (newVideos.isNotEmpty()) {
                forumVideoEntity.id = newVideos[0].id
                forumVideoEntity.url = newVideos[0].url
                forumVideoEntity.poster = newVideos[0].poster
                forumVideoEntity.status = status
                forumVideoEntity.duration = newVideos[0].duration
                forumVideoEntity.videoInfo = VideoInfo(width = newVideos[0].width, height = newVideos[0].height)
            }
        }
        return forumVideoEntity
    }
}

@Parcelize
class Count(
    @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_COUNT, SyncFieldConstants.ANSWER_COMMENT_COUNT])
    var comment: Int = 0,
    @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_VOTE_COUNT, SyncFieldConstants.ANSWER_VOTE_COUNT])
    var vote: Int = 0,
    var favorite: Int = 0,
    @SyncPage(syncNames = [SyncFieldConstants.ANSWER_COMMENT_REPLY_COUNT])
    var reply: Int = 0,
    var game: Int = 0,
    @SerializedName("game_played")
    var playedGame: Int = 0,
    var hot: Int = 0,
    var share: Int = 0,
    var question: Int = 0,
    var fans: Int = 0,
    val follower: Int = 0,
    @SerializedName("community_article")
    var communityArticle: Int = 0,
    @SerializedName("game_comment")
    val gameComment: Int = 0,
    var video: Int = 0,
    @SerializedName("game_list")
    val gameList: Int = 0,
    @SerializedName("today_visit")
    val todayVisit: Int? = 0
) : Parcelable {

    @SyncPage(syncNames = [SyncFieldConstants.ANSWER_COUNT])
    var answer: Int = 0
        get() = field + reply

    companion object : Parceler<Count> {
        override fun Count.write(parcel: Parcel, flags: Int) {
            parcel.writeInt(comment)
            parcel.writeInt(vote)
            parcel.writeInt(favorite)
            parcel.writeInt(reply)
            parcel.writeInt(answer)
        }

        override fun create(parcel: Parcel): Count {
            return Count().apply {
                comment = parcel.readInt()
                vote = parcel.readInt()
                favorite = parcel.readInt()
                reply = parcel.readInt()
                answer = parcel.readInt() - reply
            }
        }
    }
}

@Parcelize
class TimeEntity(
    var time: Long = 0,
    var create: Long = 0,
    var update: Long = 0,
    var edit: Long = 0,
    var upload: Long = 0,
    @SerializedName("edit_history")
    var editHistory: List<Long> = ArrayList()
) : Parcelable