package com.ttstd.dialer.db.app;

import android.content.ComponentName;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;

import com.google.gson.Gson;
import com.google.gson.JsonParser;
import com.ttstd.dialer.utils.ApkUtils;

import java.io.Serializable;
import java.util.Objects;

@Entity(tableName = "app_list", indices = {@Index(value = "component_name", unique = true)})
@TypeConverters({ComponentNameConverter.class})
public class AppInfo implements Serializable , Parcelable {
    private static final long serialVersionUID = 9113517079637096245L;

    @PrimaryKey(autoGenerate = true)
    private int id;
    @ColumnInfo(name = "component_name")
    private ComponentName componentName;
    @ColumnInfo(name = "label")
    private String mLabel;
    @ColumnInfo(name = "package_name")
    private String mPackageName;
    @ColumnInfo(name = "class_name")
    private String mClassName;
    @ColumnInfo(name = "position")
    private int mPosition;
    @ColumnInfo(name = "outside")
    private int outside;

    public AppInfo() {

    }

    public AppInfo(Context context, ComponentName componentName) {
        this.componentName = componentName;
        this.mLabel = ApkUtils.getAppName(context, componentName);
        this.mPackageName = componentName.getPackageName();
        this.mClassName = componentName.getClassName();
        this.mPosition = 0;
        this.outside = 0;
    }

    public AppInfo(Context context, ComponentName componentName, int pos) {
        this.componentName = componentName;
        this.mLabel = ApkUtils.getAppName(context, componentName);
        this.mPackageName = componentName.getPackageName();
        this.mClassName = componentName.getClassName();
        this.mPosition = pos;
        this.outside = 0;
    }

    protected AppInfo(Parcel in) {
        id = in.readInt();
        componentName = in.readParcelable(ComponentName.class.getClassLoader());
        mLabel = in.readString();
        mPackageName = in.readString();
        mClassName = in.readString();
        mPosition = in.readInt();
        outside = in.readInt();
    }

    public static final Creator<AppInfo> CREATOR = new Creator<AppInfo>() {
        @Override
        public AppInfo createFromParcel(Parcel in) {
            return new AppInfo(in);
        }

        @Override
        public AppInfo[] newArray(int size) {
            return new AppInfo[size];
        }
    };

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public ComponentName getComponentName() {
        return componentName;
    }

    public void setComponentName(ComponentName componentName) {
        this.componentName = componentName;
    }

    public String getLabel() {
        return mLabel;
    }

    public void setLabel(String label) {
        this.mLabel = label;
    }

    public String getPackageName() {
        return mPackageName;
    }

    public void setPackageName(String packageName) {
        this.mPackageName = packageName;
    }

    public String getClassName() {
        return mClassName;
    }

    public void setClassName(String className) {
        this.mClassName = className;
    }

    public int getPosition() {
        return mPosition;
    }

    public void setPosition(int position) {
        this.mPosition = position;
    }

    public int getOutside() {
        return outside;
    }

    public void setOutside(int outside) {
        this.outside = outside;
    }

    @Override
    public boolean equals(@Nullable @org.jetbrains.annotations.Nullable Object obj) {
        if (obj instanceof AppInfo) {
            return Objects.equals(componentName, ((AppInfo) obj).componentName);
        } else if (obj instanceof ComponentName) {
            return Objects.equals(componentName, obj);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return componentName.hashCode();
    }


    @NonNull
    @Override
    public String toString() {
        return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeParcelable(componentName, flags);
        dest.writeString(mLabel);
        dest.writeString(mPackageName);
        dest.writeString(mClassName);
        dest.writeInt(mPosition);
        dest.writeInt(outside);
    }
}
