package com.lemenzo.contacts;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.Toast;

public class SystemContactIntentActivity extends Activity {
    private static final int REQ_CONTACTS = 713;
    private boolean handled;

    @Override
    protected void onCreate(Bundle state) {
        super.onCreate(state);
        continueWhenPermitted();
    }

    private void continueWhenPermitted() {
        if (handled || isFinishing() || isDestroyed()) return;
        if (!ContactsPermission.hasReadWrite(this)) {
            ContactsPermission.requestReadWrite(this, REQ_CONTACTS);
            return;
        }
        handled = true;
        handleIntent(getIntent());
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode != REQ_CONTACTS) return;
        if (ContactsPermission.hasReadWrite(this)) {
            continueWhenPermitted();
        } else {
            Toast.makeText(this, R.string.contacts_permission_required, Toast.LENGTH_LONG).show();
            finish();
        }
    }

    private void handleIntent(Intent source) {
        if (source == null) { finish(); return; }
        String action = source.getAction();

        if (Intent.ACTION_INSERT.equals(action)) {
            openEditor(-1, source);
            return;
        }

        if (Intent.ACTION_INSERT_OR_EDIT.equals(action)) {
            showInsertOrEditChooser(source);
            return;
        }

        if ("com.android.contacts.action.SHOW_OR_CREATE_CONTACT".equals(action)) {
            long id = resolveTelOrMail(source.getData());
            if (id > 0) openDetail(id); else openEditor(-1, source);
            return;
        }

        if (Intent.ACTION_VIEW.equals(action)
                || Intent.ACTION_EDIT.equals(action)
                || ContactsContract.QuickContact.ACTION_QUICK_CONTACT.equals(action)
                || "com.android.contacts.action.QUICK_CONTACT".equals(action)) {
            long id = resolveContactId(source.getData());
            if (id > 0) {
                if (Intent.ACTION_EDIT.equals(action)) openEditor(id, source);
                else openDetail(id);
            } else {
                finish();
            }
            return;
        }

        finish();
    }

    private void showInsertOrEditChooser(Intent source) {
        final Intent preserved = new Intent(source);
        Ui.showChoiceDialog(
                this,
                getString(R.string.add_to_contacts_title),
                getString(R.string.add_to_contacts_desc),
                getString(R.string.create_new_contact),
                getString(R.string.add_to_existing_contact),
                v -> openEditor(-1, preserved),
                v -> openPicker(preserved),
                v -> finish());
    }

    private void openPicker(Intent source) {
        Intent target = new Intent(this, ContactPickerActivity.class);
        copyInsertExtras(source, target);
        startActivity(target);
        finish();
    }

    private void copyInsertExtras(Intent source, Intent target) {
        if (source == null || target == null) return;
        Uri uri = source.getData();
        if (uri != null) {
            String value = uri.getSchemeSpecificPart();
            if ("tel".equalsIgnoreCase(uri.getScheme())) target.putExtra("initial_phone", value);
            else if ("mailto".equalsIgnoreCase(uri.getScheme())) target.putExtra("initial_email", value);
        }
        String name = source.getStringExtra(ContactsContract.Intents.Insert.NAME);
        String phone = source.getStringExtra(ContactsContract.Intents.Insert.PHONE);
        String email = source.getStringExtra(ContactsContract.Intents.Insert.EMAIL);
        if (name != null) target.putExtra("initial_name", name);
        if (phone != null) target.putExtra("initial_phone", phone);
        if (email != null) target.putExtra("initial_email", email);
        int phoneType = source.getIntExtra(ContactsContract.Intents.Insert.PHONE_TYPE, -1);
        if (phoneType >= 0) target.putExtra("initial_phone_type", phoneType);
    }

    private long resolveContactId(Uri uri) {
        if (uri == null) return -1;
        try (Cursor c = getContentResolver().query(
                uri,
                new String[] { ContactsContract.Contacts._ID },
                null, null, null)) {
            if (c != null && c.moveToFirst()) return c.getLong(0);
        } catch (SecurityException e) {
            return -1;
        } catch (RuntimeException ignored) {
        }
        return -1;
    }

    private long resolveTelOrMail(Uri uri) {
        if (uri == null) return -1;
        String scheme = uri.getScheme();
        String value = uri.getSchemeSpecificPart();
        if (value == null || value.isEmpty()) return -1;

        Uri lookup;
        if ("tel".equalsIgnoreCase(scheme)) {
            lookup = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(value));
        } else if ("mailto".equalsIgnoreCase(scheme)) {
            lookup = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Email.CONTENT_FILTER_URI, Uri.encode(value));
        } else {
            return -1;
        }

        try (Cursor c = getContentResolver().query(
                lookup,
                new String[] { ContactsContract.Contacts._ID },
                null, null, null)) {
            if (c != null && c.moveToFirst()) return c.getLong(0);
        } catch (SecurityException e) {
            return -1;
        } catch (RuntimeException ignored) {
        }
        return -1;
    }

    private void openDetail(long id) {
        startActivity(new Intent(this, ContactDetailActivity.class).putExtra("contact_id", id));
        finish();
    }

    private void openEditor(long id, Intent source) {
        Intent target = new Intent(this, ContactEditorActivity.class);
        if (id > 0) target.putExtra("contact_id", id);

        copyInsertExtras(source, target);

        startActivity(target);
        finish();
    }
}
