package com.android.contacts.activities;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.LoaderManager;
import android.content.ContentUris;
import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;
import android.widget.Toast;

import com.android.contacts.AppCompatContactsActivity;
import com.android.contacts.ContactSaveService;
import com.android.contacts.R;
import com.android.contacts.common.activity.RequestPermissionsActivity;
import com.android.contacts.common.logging.EditorEvent;
import com.android.contacts.common.logging.Logger;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.util.ImplicitIntentsUtil;
import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
import com.android.contacts.editor.ContactEditorFragment;
import com.android.contacts.editor.EditorIntents;
import com.android.contacts.editor.PickRawContactDialogFragment;
import com.android.contacts.editor.PickRawContactLoader;
import com.android.contacts.editor.PickRawContactLoader.RawContactsMetadata;
import com.android.contacts.editor.SplitContactConfirmationDialogFragment;
import com.android.contacts.quickcontact.QuickContactActivity;
import com.android.contactsbind.FeedbackHelper;

/**
 * Transparent springboard activity that hosts a dialog to select a raw contact to edit.
 * All intents coming out from this activity have {@code FLAG_ACTIVITY_FORWARD_RESULT} set.
 */
public class ContactEditorSpringBoardActivity extends AppCompatContactsActivity implements
        PickRawContactDialogFragment.PickRawContactListener,
        SplitContactConfirmationDialogFragment.Listener {

    private static final String TAG = "EditorSpringBoard";
    private static final String TAG_RAW_CONTACTS_DIALOG = "rawContactsDialog";
    private static final String KEY_RAW_CONTACTS_METADATA = "rawContactsMetadata";
    private static final int LOADER_RAW_CONTACTS = 1;

    public static final String EXTRA_SHOW_READ_ONLY = "showReadOnly";

    private Uri mUri;
    private RawContactsMetadata mResult;
    private MaterialPalette mMaterialPalette;
    private boolean mHasWritableAccount;
    private boolean mShowReadOnly;
    private int mWritableAccountPosition;

    /**
     * The contact data loader listener.
     */
    protected final LoaderManager.LoaderCallbacks<RawContactsMetadata> mRawContactLoaderListener =
            new LoaderManager.LoaderCallbacks<RawContactsMetadata>() {

                @Override
                public Loader<RawContactsMetadata> onCreateLoader(int id, Bundle args) {
                    return new PickRawContactLoader(ContactEditorSpringBoardActivity.this, mUri);
                }

                @Override
                public void onLoadFinished(Loader<RawContactsMetadata> loader,
                        RawContactsMetadata result) {
                    if (result == null) {
                        toastErrorAndFinish();
                        return;
                    }
                    mResult = result;
                    onLoad();
                }

                @Override
                public void onLoaderReset(Loader<RawContactsMetadata> loader) {
                }
            };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (RequestPermissionsActivity.startPermissionActivity(this)) {
            return;
        }

        final Intent intent = getIntent();
        final String action = intent.getAction();

        if (!Intent.ACTION_EDIT.equals(action)) {
            finish();
            return;
        }
        // Just for shorter variable names.
        final String primary = ContactEditorFragment.INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR;
        final String secondary =
                ContactEditorFragment.INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR;
        if (intent.hasExtra(primary) && intent.hasExtra(secondary)) {
            mMaterialPalette = new MaterialPalette(intent.getIntExtra(primary, -1),
                    intent.getIntExtra(secondary, -1));
        }
        mShowReadOnly = intent.getBooleanExtra(EXTRA_SHOW_READ_ONLY, false);

        mUri = intent.getData();
        final String authority = mUri.getAuthority();
        final String type = getContentResolver().getType(mUri);
        // Go straight to editor if we're passed a raw contact Uri.
        if (ContactsContract.AUTHORITY.equals(authority) &&
                RawContacts.CONTENT_ITEM_TYPE.equals(type)) {
            Logger.logEditorEvent(
                    EditorEvent.EventType.SHOW_RAW_CONTACT_PICKER, /* numberRawContacts */ 0);
            final long rawContactId = ContentUris.parseId(mUri);
            startEditorAndForwardExtras(getIntentForRawContact(rawContactId));
        } else if (android.provider.Contacts.AUTHORITY.equals(authority)) {
            // Fail if given a legacy URI.
            FeedbackHelper.sendFeedback(this, TAG,
                    "Legacy Uri was passed to editor.", new IllegalArgumentException());
            toastErrorAndFinish();
        } else {
            getLoaderManager().initLoader(LOADER_RAW_CONTACTS, null, mRawContactLoaderListener);
        }
    }

    @Override
    public void onPickRawContact(long rawContactId) {
        startEditorAndForwardExtras(getIntentForRawContact(rawContactId));
    }

    /**
     * Once the load is finished, decide whether to show the dialog or load the editor directly.
     */
    private void onLoad() {
        maybeTrimReadOnly();
        setHasWritableAccount();
        if (mShowReadOnly || (mResult.rawContacts.size() > 1 && mHasWritableAccount)) {
            showDialog();
        } else {
            loadEditor();
        }
    }

    /**
     * If not configured to show read only raw contact, trim them from the result.
     */
    private void maybeTrimReadOnly() {
        mResult.showReadOnly = mShowReadOnly;
        if (mShowReadOnly) {
            return;
        }

        mResult.trimReadOnly(AccountTypeManager.getInstance(this));
    }

    /**
     * Start the dialog to pick the raw contact to edit.
     */
    private void showDialog() {
        final FragmentManager fm = getFragmentManager();
        final SplitContactConfirmationDialogFragment split =
                (SplitContactConfirmationDialogFragment) fm
                        .findFragmentByTag(SplitContactConfirmationDialogFragment.TAG);
        // If we were showing the split confirmation before show it again.
        if (split != null && split.isAdded()) {
            fm.beginTransaction().show(split).commitAllowingStateLoss();
            return;
        }
        PickRawContactDialogFragment pick = (PickRawContactDialogFragment) fm
                .findFragmentByTag(TAG_RAW_CONTACTS_DIALOG);
        if (pick == null) {
            pick = PickRawContactDialogFragment.getInstance(mResult);
            final FragmentTransaction ft = fm.beginTransaction();
            ft.add(pick, TAG_RAW_CONTACTS_DIALOG);
            // commitAllowingStateLoss is safe in this activity because the fragment entirely
            // depends on the result of the loader. Even if we lose the fragment because the
            // activity was in the background, when it comes back onLoadFinished will be called
            // again which will have all the state the picker needs. This situation should be
            // very rare, since the load should be quick.
            ft.commitAllowingStateLoss();
        }
    }

    /**
     * Starts the editor for the only writable raw contact in the cursor if one exists. Otherwise,
     * the editor is started normally and handles creation of a new writable raw contact.
     */
    private void loadEditor() {
        Logger.logEditorEvent(
                EditorEvent.EventType.SHOW_RAW_CONTACT_PICKER, /* numberRawContacts */ 0);
        final Intent intent;
        if (mHasWritableAccount) {
            intent = getIntentForRawContact(mResult.rawContacts.get(mWritableAccountPosition).id);
        } else {
            // If the contact has only read-only raw contacts, we'll want to let the editor create
            // the writable raw contact for it.
            intent = EditorIntents.createEditContactIntent(this, mUri, mMaterialPalette, -1);
            intent.setClass(this, ContactEditorActivity.class);
        }
        startEditorAndForwardExtras(intent);
    }

    /**
     * Determines if this contact has a writable account.
     */
    private void setHasWritableAccount() {
        mWritableAccountPosition = mResult.getIndexOfFirstWritableAccount(
                AccountTypeManager.getInstance(this));
        mHasWritableAccount = mWritableAccountPosition != -1;
    }

    /**
     * Returns an intent to load the editor for the given raw contact. Sets
     * {@code FLAG_ACTIVITY_FORWARD_RESULT} in case the activity that started us expects a result.
     * @param rawContactId Raw contact to edit
     */
    private Intent getIntentForRawContact(long rawContactId) {
        final Intent intent = EditorIntents.createEditContactIntentForRawContact(
                this, mUri, rawContactId, mMaterialPalette);
        intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        return intent;
    }

    /**
     * Starts the given intent within the app, attaching any extras to it that were passed to us.
     */
    private void startEditorAndForwardExtras(Intent intent) {
        final Bundle extras = getIntent().getExtras();
        if (extras != null) {
            intent.putExtras(extras);
        }
        ImplicitIntentsUtil.startActivityInApp(this, intent);
        finish();
    }

    private void toastErrorAndFinish() {
        Toast.makeText(ContactEditorSpringBoardActivity.this,
                R.string.editor_failed_to_load, Toast.LENGTH_SHORT).show();
        setResult(RESULT_CANCELED, null);
        finish();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Ignore failed requests
        if (resultCode != Activity.RESULT_OK) {
            finish();
        }
        if (data != null) {
            final Intent intent = ContactSaveService.createJoinContactsIntent(
                    this, mResult.contactId, ContentUris.parseId(data.getData()),
                    QuickContactActivity.class, Intent.ACTION_VIEW);
            startService(intent);
            finish();
        }
    }

    @Override
    public void onSplitContactConfirmed(boolean hasPendingChanges) {
        final long[][] rawContactIds = getRawContactIds();
        final Intent intent = ContactSaveService.createHardSplitContactIntent(this, rawContactIds);
        startService(intent);
        finish();
    }

    @Override
    public void onSplitContactCanceled() {
        finish();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(KEY_RAW_CONTACTS_METADATA, mResult);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mResult = savedInstanceState.getParcelable(KEY_RAW_CONTACTS_METADATA);
    }

    private long[][] getRawContactIds() {
        final long[][] result = new long[mResult.rawContacts.size()][1];
        for (int i = 0; i < mResult.rawContacts.size(); i++) {
            result[i][0] = mResult.rawContacts.get(i).id;
        }
        return result;
    }
}
