/*
 * Copyright 2019 Uriah Shaul Mandel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.bald.uriah.baldphone.activities.contacts;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.RecyclerView;

import com.bald.uriah.baldphone.R;
import com.bald.uriah.baldphone.activities.BaldActivity;
import com.bald.uriah.baldphone.activities.DialerActivity;
import com.bald.uriah.baldphone.activities.SOSActivity;
import com.bald.uriah.baldphone.adapters.CallsRecyclerViewAdapter;
import com.bald.uriah.baldphone.databases.calls.Call;
import com.bald.uriah.baldphone.databases.calls.CallLogsHelper;
import com.bald.uriah.baldphone.databases.contacts.Contact;
import com.bald.uriah.baldphone.databases.home_screen_pins.HomeScreenPinHelper;
import com.bald.uriah.baldphone.utils.BDB;
import com.bald.uriah.baldphone.utils.BDialog;
import com.bald.uriah.baldphone.utils.BaldToast;
import com.bald.uriah.baldphone.utils.S;
import com.bald.uriah.baldphone.utils.Toggeler;
import com.bald.uriah.baldphone.views.BaldLinearLayoutButton;
import com.bald.uriah.baldphone.views.BaldPictureTextButton;
import com.bald.uriah.baldphone.views.BaldTitleBar;
import com.bald.uriah.baldphone.views.ScrollingHelper;
import com.bumptech.glide.Glide;

import java.util.List;

/**
 * Simple Activity for interacting with a {@link Contact}.
 * {@link #CONTACT_ID} or {@link #CONTACT_LOOKUP_KEY} must be added
 */
public class SingleContactActivity extends BaldActivity {
    private static final String TAG = SingleContactActivity.class.getSimpleName();
    public static final String CONTACT_ID = "CONTACT_ID";
    public static final String CONTACT_LOOKUP_KEY = "CONTACT_KEY";
    public static final String PIC_URI_EXTRA = "PIC_URI_EXTRA";
    /**
     * request check if deleted contact, if returns {@link Activity#RESULT_OK} contact was deleted.
     */
    public static final int REQUEST_CHECK_CHANGE = 97;
    public static boolean newPictureAdded = false;
    private boolean viaId = false;
    private String contactKeyExtra;
    private BaldTitleBar baldTitleBar;
    private ImageView contact_image;
    private LinearLayout ll;
    private MediaPlayer mediaPlayer;
    private ContentResolver contentResolver;
    private LayoutInflater layoutInflater;
    private Contact contact; //final
    private boolean changed;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.single_contact_activity);
        attachXml();
        contentResolver = getContentResolver();
        layoutInflater = getLayoutInflater();
        final Intent callingIntent = getIntent();
        viaId = callingIntent.hasExtra(CONTACT_ID);
        contactKeyExtra =
                viaId ?
                        callingIntent.getStringExtra(CONTACT_ID)
                        :
                        callingIntent.getStringExtra(CONTACT_LOOKUP_KEY)
        ;
        callingIntent.removeExtra(PIC_URI_EXTRA);

    }

    @Override
    protected void onStart() {
        super.onStart();

        final int childCount = ll.getChildCount();
        if (childCount > 2)
            ll.removeViews(2, ll.getChildCount() - 2);

        try {
            contact = viaId ?
                    Contact.fromId(contactKeyExtra, contentResolver) :
                    Contact.fromLookupKey(contactKeyExtra, contentResolver);
        } catch (Contact.ContactNotFoundException e) {
            finish();
            return;
        }

        baldTitleBar.setTitle(contact.getName());
        setupBar();

        if (contact.hasPhone())
            inflatePhones();

        if (contact.hasWhatsapp())
            inflateWhatsapp();

        if (contact.hasMail())
            inflateMails();

        if (contact.hasAddress())
            inflateAddresses();

        if (newPictureAdded)
            new Handler().postDelayed(() -> {
                newPictureAdded = false;
                String uri = null;
                try (final Cursor cursor =
                             contentResolver.query(
                                     ContactsContract.Contacts.CONTENT_URI,
                                     new String[]{
                                             ContactsContract.Contacts.PHOTO_URI},
                                     (viaId ?
                                             ContactsContract.Contacts._ID :
                                             ContactsContract.Contacts.LOOKUP_KEY)
                                             + " = ?",
                                     new String[]{contactKeyExtra},
                                     null)) {
                    if (cursor.moveToFirst())
                        uri = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI));
                }
                if (uri != null) {
                    loadPhoto(uri);
                } else
                    contact_image.setVisibility(View.GONE);

            }, 1000);

        else {
            if (contact.hasPhoto())
                loadPhoto(contact.getPhoto());
            else
                contact_image.setVisibility(View.GONE);
        }

        inflateAdders();

        final List<Call> callList =
                CallLogsHelper.getForSpecificContact(contentResolver, contact);
        if (!callList.isEmpty())
            inflateHistory(callList);

    }

    @Override
    protected void onStop() {
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }

        super.onStop();

    }

    private void attachXml() {
        baldTitleBar = findViewById(R.id.bald_title_bar);
        ll = findViewById(R.id.ll_info);
        contact_image = findViewById(R.id.contact_image);
    }

    private void inflatePhones() {
        final List<Pair<Integer, String>> phoneList = contact.getPhoneList(); //removing dup
        for (int i = 0, phoneListSize = phoneList.size(); i < phoneListSize - 1; i++) {
            final Pair<Integer, String> pair = phoneList.get(i);
            final Pair<Integer, String> next = phoneList.get(i + 1);
            if (pair.second
                    .replaceAll("[^0123456789]", "")
                    .equals(next.second
                            .replaceAll("[^0123456789]", ""))) {
                phoneList.remove(pair);
                phoneListSize--;
                i--;
            }
        }

        for (final Pair<Integer /*Type*/ , String> pair : contact.getPhoneList()) {
            View layout = layoutInflater.inflate(R.layout.contact_number, ll, false);
            final TextView tv_type = layout.findViewById(R.id.tv_type);
            final TextView tv_value = layout.findViewById(R.id.tv_value);
            final BaldLinearLayoutButton call = layout.findViewById(R.id.call);
            final BaldLinearLayoutButton message = layout.findViewById(R.id.message);

            tv_type.setText(ContactsContract.CommonDataKinds.Phone.getTypeLabel(
                    getResources(),
                    pair.first,
                    "Custom"));
            tv_value.setText(pair.second);
            call.setOnClickListener(v -> DialerActivity.call(pair.second, this, false));
            message.setOnClickListener(v -> S.sendMessage(pair.second, this));

            ll.addView(layout);
        }

    }

    private void inflateWhatsapp() {
        final List<String> whatappNumbers = contact.getWhatsappNumbers();
        for (String whatappNumber : whatappNumbers) {
            final View layout = layoutInflater.inflate(R.layout.contact_whatsapp, ll, false);
            layout.findViewById(R.id.whatsapp).setOnClickListener((v) ->
                    startActivity(
                            new Intent("android.intent.activate.MAIN")
                                    .setComponent(new ComponentName("com.whatsapp", "com.whatsapp.Conversation"))
                                    .putExtra("jid",
                                            PhoneNumberUtils.stripSeparators(
                                                    whatappNumber
                                                            .replaceAll(
                                                                    "[^0123456789]",
                                                                    "")
                                            ) + "@s.whatsapp.net")
                    )
            );
            ll.addView(layout);
        }
    }

    private void inflateMails() {
        final List<String> mailList = contact.getMailList();
        for (int i = 0, mailListSize = mailList.size(); i < mailListSize - 1; i++) {
            final String phone = mailList.get(i);
            final String next = mailList.get(i + 1);
            if (phone.equals(next)) {
                mailList.remove(i);
                mailListSize--;
                i--;
            }
        }
        for (final String phone : contact.getMailList()) {
            final View layout = layoutInflater.inflate(R.layout.contact_mail, ll, false);
            final TextView tv_value = layout.findViewById(R.id.tv_value);
            final BaldLinearLayoutButton mail = layout.findViewById(R.id.mail);
            tv_value.setText(phone);
            mail.setOnClickListener(v -> {
                final Intent intent = new Intent(Intent.ACTION_SEND)
                        .setType("text/html")
                        .putExtra(Intent.EXTRA_EMAIL, phone);
                startActivity(intent);

            });
            ll.addView(layout);
        }

    }

    private void inflateAdders() {
        final View view = layoutInflater.inflate(R.layout.contact_add_to, ll, false);
        final BaldPictureTextButton
                home = view.findViewById(R.id.home),
                favorite = view.findViewById(R.id.favorite),
                sos = view.findViewById(R.id.sos);

        Toggeler.newTextImageToggeler(
                home,
                home.getImageView(),
                home.getTextView(),
                new int[]{R.drawable.home_on_button, R.drawable.remove_on_button},
                new int[]{R.string.add_to_home, R.string.remove_from_home},
                new View.OnClickListener[]{
                        (v) -> HomeScreenPinHelper.removeContact(v.getContext(), contact.getLookupKey()),
                        (v) -> HomeScreenPinHelper.pinContact(v.getContext(), contact.getLookupKey())
                },
                HomeScreenPinHelper.isPinned(this, contact.getLookupKey()) ? 1 : 0
        );

        Toggeler.newTextImageToggeler(
                sos,
                sos.getImageView(),
                sos.getTextView(),
                new int[]{R.drawable.emergency, R.drawable.remove_on_button},
                new int[]{R.string.add_to_sos, R.string.remove_from_sos},
                new View.OnClickListener[]{
                        (v) -> SOSActivity.PinHelper.removeContact(v.getContext(), contact.getLookupKey()),
                        (v) -> {
                            if (!SOSActivity.PinHelper.pinContact(v.getContext(), contact.getLookupKey())) {
                                BDB.from(v.getContext())
                                        .setTitle(R.string.sos_is_full)
                                        .setSubText(R.string.sos_is_full_subtext)
                                        .addFlag(BDialog.FLAG_OK)
                                        .show();
                                v.setVisibility(View.GONE);
                            }
                        }
                },
                SOSActivity.PinHelper.isPinned(this, contact.getLookupKey()) ? 1 : 0
        );

        final ContentValues STAR = new ContentValues();
        STAR.put(ContactsContract.Contacts.STARRED, 1);
        final ContentValues UNSTAR = new ContentValues();
        UNSTAR.put(ContactsContract.Contacts.STARRED, 0);
        baldTitleBar.setGold(contact.isFavorite());
        Toggeler.newTextImageToggeler(
                favorite,
                favorite.getImageView(),
                favorite.getTextView(),
                new int[]{R.drawable.star_on_button, R.drawable.star_remove_on_button},
                new int[]{R.string.add_to_favorite, R.string.remove_from_favorite},
                new View.OnClickListener[]{
                        (v) -> {
                            contentResolver.update(
                                    ContactsContract.Contacts.CONTENT_URI,
                                    UNSTAR,
                                    ContactsContract.Contacts.LOOKUP_KEY + "=?",
                                    new String[]{contact.getLookupKey()});
                            baldTitleBar.setGold(false);
                            changed = true;
                        },
                        (v) -> {
                            contentResolver.update(
                                    ContactsContract.Contacts.CONTENT_URI,
                                    STAR,
                                    ContactsContract.Contacts.LOOKUP_KEY + "=?",
                                    new String[]{contact.getLookupKey()});
                            baldTitleBar.setGold(true);
                            changed = true;
                        }
                },
                contact.isFavorite() ? 1 : 0

        );
        ll.addView(view);
    }

    private void inflateAddresses() {
        for (Pair<Integer, String[]> pair : contact.getAddressList()) {
            final View layout = layoutInflater.inflate(R.layout.contact_address, ll, false);
            final TextView tv_addressType = layout.findViewById(R.id.tv_address);
            final BaldPictureTextButton button = layout.findViewById(R.id.address_button);
            tv_addressType.setText(
                    String.format("%s %s",
                            String.valueOf(ContactsContract.CommonDataKinds.SipAddress.getTypeLabel(getResources(),
                                    pair.first,
                                    getText(R.string.custom)))
                            , String.valueOf(getText(R.string.address)
                            )
                    )
            );

            final StringBuilder stringBuilder = new StringBuilder();
            for (final String s : pair.second) {
                if (s == null || s.equals(""))
                    continue;

                stringBuilder.append(s).append(" ");

            }
            button.setText(stringBuilder);
            button.setOnClickListener(v -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + stringBuilder))));

            ll.addView(layout);
        }
    }

    private void inflateHistory(List<Call> callList) {
        final View view = layoutInflater.inflate(R.layout.contact_history, ll, false);
        final ScrollingHelper scrollingHelper = view.findViewById(R.id.scrolling_helper);
        final RecyclerView recyclerView = scrollingHelper.findViewById(R.id.child);
        final DividerItemDecoration dividerItemDecoration =
                new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
        dividerItemDecoration.setDrawable(getDrawable(R.drawable.ll_divider));
        recyclerView.addItemDecoration(dividerItemDecoration);
        recyclerView.setAdapter(new CallsRecyclerViewAdapter(callList, this));

        final BaldPictureTextButton show = view.findViewById(R.id.bt_show);
        Toggeler.newSimpleTextImageToggeler(
                show,
                show.getImageView(),
                show.getTextView(),
                R.drawable.drop_down_on_button,
                R.drawable.drop_up_on_button,
                R.string.show,
                R.string.hide,
                v -> scrollingHelper.setVisibility(View.VISIBLE),
                v -> scrollingHelper.setVisibility(View.GONE));
        ll.addView(view);
    }

    private void setupBar() {
        final Intent editIntent =
                new Intent(this, AddContactActivity.class)
                        .putExtra(CONTACT_LOOKUP_KEY, contact.getLookupKey());
        final View.OnClickListener deleteListener = (v) ->
                BDB.from(this)
                        .addFlag(BDialog.FLAG_YES | BDialog.FLAG_CANCEL)
                        .setSubText(String.format(getString(R.string.are_you_sure_you_want_to_delete___), contact.getName()))
                        .setPositiveButtonListener(params -> {
                            deleteContact();
                            return true;
                        })
                        .show();
        findViewById(R.id.bt_delete).setOnClickListener(deleteListener);
        findViewById(R.id.bt_edit).setOnClickListener(v -> v.getContext().startActivity(editIntent));

        final Uri vcardUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, contact.getLookupKey());
        final Intent shareIntent = new Intent(Intent.ACTION_SEND)
                .setType(ContactsContract.Contacts.CONTENT_VCARD_TYPE)
                .putExtra(Intent.EXTRA_STREAM, vcardUri)
                .putExtra(Intent.EXTRA_SUBJECT, contact.getName());

        findViewById(R.id.bt_share).setOnClickListener(v -> {
                    changed = true;
                    S.share(this, shareIntent);
                }
        );

    }

    private void deleteContact() {
        contentResolver.delete(
                Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, contact.getLookupKey()),
                null,
                null);
        changed = true;
        finish();
    }

    @Override
    public void finish() {
        if (changed) setResult(RESULT_OK);
        super.finish();
    }

    private void loadPhoto(String uriToLoad) {
        if (S.isValidContextForGlide(contact_image.getContext()))
            Glide.with(contact_image).load(uriToLoad).into(contact_image);
    }

    @Override
    public void startActivity(Intent intent) {
        try {
            super.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Log.e(TAG, e.getMessage());
            e.printStackTrace();
            BaldToast.error(this);
        }
    }

    @Override
    protected int requiredPermissions() {
        return PERMISSION_WRITE_CONTACTS | PERMISSION_READ_CONTACTS | PERMISSION_CALL_PHONE | PERMISSION_WRITE_CALL_LOG;
    }
}