package com.shukria.softpos.ui;

import com.mypinpad.android.hapticslibrary.CardScheme;
import com.mypinpad.tsdk.api.TerminalSession;
import com.mypinpad.tsdk.api.callbacks.SessionActivationFailureCause;
import com.mypinpad.tsdk.api.callbacks.UiMessage;

public class ViewData {

    public final HoldStrategy holdStrategy;

    protected ViewData(HoldStrategy holdStrategy) {
        this.holdStrategy = holdStrategy;
    }

    protected ViewData() {
        this(HoldStrategy.None);
    }

    public void onCleared() {
    }

    public static class HoldStrategy {
        /**
         * No hold, display the UI represented by this [ViewData] until another
         * [ViewData] comes along
         */
        public static HoldStrategy None = new HoldStrategy();

        /**
         * Hold this view on screen for [ms] milliseconds.
         */
        public static class Milliseconds extends HoldStrategy {
            public long ms;

            Milliseconds(long ms) {
                this.ms = ms;
            }
        }

        /**
         * Display the UI represented by this [ViewData] until told by the the UI (ie
         * the Activity)
         * that it is done. Used for animations.
         */
        public static HoldStrategy UiControlled = new HoldStrategy();
    }

    public static class TerminalNotCreatedViewData extends ViewData {
        public TerminalNotCreatedViewData() {
            super();
        }
    }

    public static class TerminalInitialisingViewData extends ViewData {
        public TerminalInitialisingViewData() {
            super();
        }
    }

    public static class TerminalReadyViewData extends ViewData {
        public TerminalReadyViewData() {
            super();
        }
    }

    public static class TerminalActivatingViewData extends ViewData {
        public TerminalActivatingViewData() {
            super();
        }
    }

    public static class TerminalSessionTimeoutViewData extends ViewData {
        public TerminalSessionTimeoutViewData() {
            super();
        }
    }

    public static class TerminalInSessionViewData extends ViewData {
        public TerminalSession session;

        public TerminalInSessionViewData(TerminalSession session) {
            super();

            this.session = session;
        }

        @Override
        public void onCleared() {
            session.deactivate();
        }
    }

    public static class TerminalInProcessingViewData extends ViewData {
        public final TerminalSession session;
        public final UiMessage uiMessage;

        public TerminalInProcessingViewData(TerminalSession session, UiMessage uiMessage) {
            super(new HoldStrategy.Milliseconds(uiMessage != null ? uiMessage.getHoldTime() : 0L));

            this.session = session;
            this.uiMessage = uiMessage;
        }

        public TerminalInProcessingViewData(TerminalSession session) {
            this(session, null);
        }

        @Override
        public void onCleared() {
            session.deactivate();
        }
    }

    public static class ProcessingFinishedViewData extends ViewData {

        public final String logMessage;
        public final UiMessage uiMessage;

        public ProcessingFinishedViewData(
                String logMessage,
                UiMessage uiMessage,
                long minimumHoldTimeMs) {

            super(new HoldStrategy.Milliseconds(
                    Math.max(
                            minimumHoldTimeMs,
                            uiMessage != null ? uiMessage.getHoldTime() : 0L)));

            this.logMessage = logMessage;
            this.uiMessage = uiMessage;
        }

        public ProcessingFinishedViewData(String logMessage, UiMessage uiMessage) {
            this(logMessage, uiMessage, 3000L);
        }

        public ProcessingFinishedViewData(String logMessage) {
            this(logMessage, null, 3000L);
        }
    }

    public static class DisplaySchemeHapticsViewData extends ViewData {
        public final CardScheme cardScheme;

        public DisplaySchemeHapticsViewData(CardScheme cardScheme) {
            super(HoldStrategy.UiControlled);

            this.cardScheme = cardScheme;
        }
    }

    public static class SessionErrorViewData extends ViewData {
        public final SessionActivationFailureCause cause;
        public final Throwable exception;

        public SessionErrorViewData(SessionActivationFailureCause cause, Throwable exception) {
            super();

            this.cause = cause;
            this.exception = exception;
        }
    }

    public static class TerminalErrorViewData extends ViewData {

        public final Throwable cause;
        public final String logMessage;

        public TerminalErrorViewData(
                Throwable cause,
                String logMessage) {
            super();

            this.cause = cause;
            this.logMessage = logMessage;
        }

        public TerminalErrorViewData(
                Throwable cause) {
            this(cause, getCauses(cause));
        }
    }

    private static String getCauses(Throwable throwable) {
        return "causedBy[" + throwable + "]\n" +
                (throwable.getCause() == null ? "" : getCauses(throwable.getCause()));
    }

}
