package ab.issue.model.values;

import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import android.arch.persistence.room.TypeConverters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.google.common.base.MoreObjects;
import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcode;
import com.google.zxing.client.result.WifiParsedResult;

import java.util.List;
import java.util.Locale;

import ab.issue.db.BarcodeDatabase;
import ab.issue.db.DbConstants;
import ab.issue.model.Barcode;
import androidx.navigation.NavController;

import static com.google.common.base.Optional.fromNullable;

@SuppressWarnings("Guava")
@Entity(
        tableName = DbConstants.WIFI_TABLE_NAME,
        foreignKeys = @ForeignKey(
                entity = Barcode.class,
                parentColumns = DbConstants.COLUMN_NAME_BARCODE_ID,
                childColumns = DbConstants.COLUMN_NAME_WIFI_BARCODE_ID,
                onUpdate = ForeignKey.CASCADE,
                onDelete = ForeignKey.CASCADE
        ),
        indices = @Index(value = DbConstants.COLUMN_NAME_WIFI_BARCODE_ID, unique = true)
)
public class WifiBarcodeFormat implements BarcodeFormatValue {

    public static WifiBarcodeFormat create(@Nullable FirebaseVisionBarcode.WiFi wiFi) {
        if (wiFi == null) {
            return new WifiBarcodeFormat();
        }
        return new WifiBarcodeFormat(wiFi.getSsid(), wiFi.getPassword(), WifiEncryptionType.from(wiFi));
    }

    public static BarcodeFormatValue create(WifiParsedResult wifiParsedResult) {
        if (wifiParsedResult == null) {
            return new WifiBarcodeFormat();
        }
        return new WifiBarcodeFormat(wifiParsedResult.getSsid(), wifiParsedResult.getPassword(),
                WifiEncryptionType.from(wifiParsedResult));
    }

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = DbConstants.COLUMN_NAME_WIFI_ID)
    private long id;

    @ColumnInfo(name = DbConstants.COLUMN_NAME_WIFI_BARCODE_ID)
    private long barcodeId;

    @ColumnInfo(name = DbConstants.COLUMN_NAME_WIFI_SSID)
    private String ssid;

    @TypeConverters(WifiEncryptionType.class)
    @ColumnInfo(name = DbConstants.COLUMN_NAME_WIFI_ENCRYPTION_TYPE)
    private WifiEncryptionType wifiEncryptionType;

    @ColumnInfo(name = DbConstants.COLUMN_NAME_WIFI_PASSWORD)
    private String password;

    public WifiBarcodeFormat() {
    }

    private WifiBarcodeFormat(String ssid, String password, WifiEncryptionType wifiEncryptionType) {
        this.ssid = ssid;
        this.password = password;
        this.wifiEncryptionType = wifiEncryptionType;
    }

    @Override
    public String getName(Context context) {
        return null;
    }

    @Override
    public BarcodeFormatValueType getType() {
        return BarcodeFormatValueType.WIFI;
    }

    @Override
    public String encode() {
        WifiEncryptionType wifiEncryptionType = fromNullable(getWifiEncryptionType()).or(WifiEncryptionType.OPEN);
        String ssid = fromNullable(getSsid()).or("");
        String password = fromNullable(getPassword()).or("");
        return String.format(Locale.ENGLISH, "WIFI:T:%s;S:%s;P:%s;;",
                wifiEncryptionType.getEncodingName(), ssid, password);
    }

    @NonNull
    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("ssid", ssid)
                .add("wifiEncryption", wifiEncryptionType)
                .add("password", password)
                .omitNullValues()
                .toString();
    }

    @Override
    public void save(BarcodeDatabase barcodeDatabase) {
        barcodeDatabase.wifiValueDao().insert(this);
    }

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

    @Override
    public void setBarcodeId(long barcodeId) {
        this.barcodeId = barcodeId;
    }

    @Override
    public void create(NavController navController) {

    }

    @Override
    public List<Barcode> search(BarcodeDatabase barcodeDatabase, String query) {
        return barcodeDatabase.wifiValueDao().findTextInBarcodeFormatValues(query);
    }

    public long getId() {
        return id;
    }

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

    public long getBarcodeId() {
        return barcodeId;
    }

    public String getSsid() {
        return ssid;
    }

    public void setSsid(String ssid) {
        this.ssid = ssid;
    }

    public WifiEncryptionType getWifiEncryptionType() {
        return wifiEncryptionType;
    }

    public void setWifiEncryptionType(WifiEncryptionType wifiEncryptionType) {
        this.wifiEncryptionType = wifiEncryptionType;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

