package ab.issue.model.formats;

import com.google.common.base.MoreObjects;

import java.util.List;

import javax.annotation.Nonnull;

import ab.issue.model.values.BarcodeFormatValue;
import ab.issue.model.values.CalendarEventBarcodeFormat;
import ab.issue.model.values.ContactInfoBarcodeFormat;
import ab.issue.model.values.EmailBarcodeFormat;
import ab.issue.model.values.GeoBarcodeFormat;
import ab.issue.model.values.PhoneBarcodeFormat;
import ab.issue.model.values.SmsBarcodeFormat;
import ab.issue.model.values.TextBarcodeFormat;
import ab.issue.model.values.UnknownBarcodeFormatValue;
import ab.issue.model.values.UrlBarcodeFormat;
import ab.issue.model.values.WifiBarcodeFormat;

abstract class BaseBarcodeFormat implements ab.issue.model.formats.BarcodeFormat {

    private BarcodeFormatValue value;

    BaseBarcodeFormat(BarcodeFormatValue value) {
        this.value = value;
    }

    @Override
    public BarcodeFormatValue getValue() {
        return value;
    }

    @Override
    public void setValue(List<CalendarEventBarcodeFormat> calendarEvents,
                         List<ContactInfoBarcodeFormat> contacts,
                         List<EmailBarcodeFormat> emails,
                         List<GeoBarcodeFormat> geo,
                         List<PhoneBarcodeFormat> phones,
                         List<SmsBarcodeFormat> sms,
                         List<UrlBarcodeFormat> urls,
                         List<WifiBarcodeFormat> wifi) {
        switch (getType()) {
            case AZTEC:
            case CODABAR:
            case CODE_128:
            case CODE_39:
            case CODE_93:
            case DATA_MATRIX:
            case EAN_13:
            case EAN_8:
            case ITF:
            case PDF_417:
            case UPC_A:
            case UPC_E:
                value = new TextBarcodeFormat();
                break;
            case QR_CODE:
                value = getQrCodeValue(calendarEvents, contacts, emails, geo, phones, sms, urls, wifi);
                break;
            case UNKNOWN:
            default:
                value = new UnknownBarcodeFormatValue();
                break;
        }
    }

    @Override
    public void setValue(BarcodeFormatValue value) {
        this.value = value;
    }

    @Nonnull
    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("zxingFormat", getZxingBarcodeFormat())
                .add("type", getType())
                .add("value", value)
                .toString();
    }

    private BarcodeFormatValue getQrCodeValue(List<CalendarEventBarcodeFormat> calendarEvents,
                                              List<ContactInfoBarcodeFormat> contacts,
                                              List<EmailBarcodeFormat> emails,
                                              List<GeoBarcodeFormat> geo,
                                              List<PhoneBarcodeFormat> phones,
                                              List<SmsBarcodeFormat> sms,
                                              List<UrlBarcodeFormat> urls,
                                              List<WifiBarcodeFormat> wifi) {
        BarcodeFormatValue value = getFirstItem(calendarEvents);
        if (value != null) {
            return value;
        }
        value = getFirstItem(contacts);
        if (value != null) {
            return value;
        }
        value = getFirstItem(emails);
        if (value != null) {
            return value;
        }
        value = getFirstItem(geo);
        if (value != null) {
            return value;
        }
        value = getFirstItem(phones);
        if (value != null) {
            return value;
        }
        value = getFirstItem(sms);
        if (value != null) {
            return value;
        }
        value = getFirstItem(urls);
        if (value != null) {
            return value;
        }
        value = getFirstItem(wifi);
        if (value != null) {
            return value;
        }
        return new TextBarcodeFormat();
    }

    private <T extends BarcodeFormatValue> BarcodeFormatValue getFirstItem(List<T> list) {
//        return CollectionUtils.isEmpty(list) ? null : list.get(0);
        return null;
    }
}
