/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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.android.car.dialer;

import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.car.dialer.telecom.TelecomUtils;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;
import androidx.car.utils.ListItemBackgroundResolver;
import androidx.car.widget.DayNightStyle;
import androidx.car.widget.PagedListView;
import androidx.fragment.app.Fragment;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.RecyclerView;

/**
 * A fragment that shows the name of the contact, the photo and all listed phone numbers. It is
 * primarily used to respond to the results of search queries but supplyig it with the content://
 * uri of a contact should work too.
 */
public class ContactDetailsFragment extends Fragment
        implements LoaderManager.LoaderCallbacks<Cursor> {
    private static final String TAG = "ContactDetailsFragment";
    private static final String TELEPHONE_URI_PREFIX = "tel:";

    private static final int DETAILS_LOADER_QUERY_ID = 1;
    private static final int PHONE_LOADER_QUERY_ID = 2;

    private static final String KEY_URI = "uri";

    private static final String[] CONTACT_DETAILS_PROJECTION = {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.PHOTO_URI,
            ContactsContract.Contacts.HAS_PHONE_NUMBER
    };

    private PagedListView mListView;
    private List<RecyclerView.OnScrollListener> mOnScrollListeners = new ArrayList<>();

    public static ContactDetailsFragment newInstance(Uri uri,
            @Nullable RecyclerView.OnScrollListener listener) {
        ContactDetailsFragment fragment = new ContactDetailsFragment();
        if (listener != null) {
            fragment.addOnScrollListener(listener);
        }

        Bundle args = new Bundle();
        args.putParcelable(KEY_URI, uri);
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.contact_details, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        mListView = view.findViewById(R.id.list_view);
        mListView.setDayNightStyle(DayNightStyle.ALWAYS_LIGHT);

        RecyclerView recyclerView = mListView.getRecyclerView();
        for (RecyclerView.OnScrollListener listener : mOnScrollListeners) {
            recyclerView.addOnScrollListener(listener);
        }

        mOnScrollListeners.clear();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getLoaderManager().initLoader(DETAILS_LOADER_QUERY_ID, null, this);
    }

    /**
     * Adds a {@link androidx.recyclerview.widget.RecyclerView.OnScrollListener} to be notified when
     * the contact details are scrolled.
     *
     * @see RecyclerView#addOnScrollListener(RecyclerView.OnScrollListener)
     */
    public void addOnScrollListener(RecyclerView.OnScrollListener onScrollListener) {
        // If the view has not been created yet, then queue the setting of the scroll listener.
        if (mListView == null) {
            mOnScrollListeners.add(onScrollListener);
            return;
        }

        mListView.getRecyclerView().addOnScrollListener(onScrollListener);
    }

    @Override
    public void onDestroy() {
        // Clear all scroll listeners.
        mListView.getRecyclerView().removeOnScrollListener(null);
        super.onDestroy();
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        if (vdebug()) {
            Log.d(TAG, "onCreateLoader id=" + id);
        }

        if (id != DETAILS_LOADER_QUERY_ID) {
            return null;
        }

        Uri contactUri = getArguments().getParcelable(KEY_URI);
        return new CursorLoader(getContext(), contactUri, CONTACT_DETAILS_PROJECTION,
                null /* selection */, null /* selectionArgs */, null /* sortOrder */);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        if (vdebug()) {
            Log.d(TAG, "onLoadFinished");
        }

        if (cursor.moveToFirst()) {
            mListView.setAdapter(new ContactDetailsAdapter(cursor));
        }
    }

    @Override
    public void onLoaderReset(Loader loader) {
    }

    private boolean vdebug() {
        return Log.isLoggable(TAG, Log.DEBUG);
    }

    private class ContactDetailViewHolder extends RecyclerView.ViewHolder {
        public View card;
        public ImageView leftIcon;
        public TextView title;
        public TextView text;
        public ImageView avatar;
        public View divier;

        public ContactDetailViewHolder(View v) {
            super(v);
            card = v.findViewById(R.id.card);
            leftIcon = v.findViewById(R.id.icon);
            title = v.findViewById(R.id.title);
            text = v.findViewById(R.id.text);
            avatar = v.findViewById(R.id.avatar);
            divier = v.findViewById(R.id.divider);
        }
    }

    private class ContactDetailsAdapter extends RecyclerView.Adapter<ContactDetailViewHolder>
            implements PagedListView.ItemCap {

        private static final int ID_HEADER = 1;
        private static final int ID_CONTENT = 2;

        private final String mContactName;
        @ColorInt
        private int mIconTint;

        private List<Pair<String, String>> mPhoneNumbers = new ArrayList<>();

        public ContactDetailsAdapter(Cursor cursor) {
            super();

            mIconTint = getContext().getColor(R.color.contact_details_icon_tint);

            int idColIdx = cursor.getColumnIndex(ContactsContract.Contacts._ID);
            String contactId = cursor.getString(idColIdx);
            int nameColIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
            mContactName = cursor.getString(nameColIdx);
            int hasPhoneColIdx = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
            boolean hasPhoneNumber = Integer.parseInt(cursor.getString(hasPhoneColIdx)) > 0;

            if (!hasPhoneNumber) {
                return;
            }

            // Fetch the phone number from the contacts db using another loader.
            LoaderManager.getInstance(ContactDetailsFragment.this).initLoader(PHONE_LOADER_QUERY_ID,
                    null,
                    new LoaderManager.LoaderCallbacks<Cursor>() {
                        @Override
                        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                            return new CursorLoader(getContext(),
                                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                    null, /* All columns **/
                                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                                    new String[]{contactId},
                                    null /* sortOrder */);
                        }

                        public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
                            while (cursor.moveToNext()) {
                                int typeColIdx = cursor.getColumnIndex(
                                        ContactsContract.CommonDataKinds.Phone.TYPE);
                                int type = cursor.getInt(typeColIdx);
                                int numberColIdx = cursor.getColumnIndex(
                                        ContactsContract.CommonDataKinds.Phone.NUMBER);
                                String number = cursor.getString(numberColIdx);
                                String numberType;
                                switch (type) {
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
                                        numberType = getString(R.string.type_home);
                                        break;
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
                                        numberType = getString(R.string.type_work);
                                        break;
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
                                        numberType = getString(R.string.type_mobile);
                                        break;
                                    default:
                                        numberType = getString(R.string.type_other);
                                }
                                mPhoneNumbers.add(new Pair<>(numberType,
                                        TelecomUtils.getFormattedNumber(getContext(), number)));
                                notifyItemInserted(mPhoneNumbers.size());
                            }
                            notifyDataSetChanged();
                        }

                        public void onLoaderReset(Loader loader) {
                        }
                    });
        }

        @Override
        public int getItemViewType(int position) {
            return position == 0 ? ID_HEADER : ID_CONTENT;
        }

        @Override
        public void setMaxItems(int maxItems) {
            // Ignore.
        }

        @Override
        public int getItemCount() {
            return mPhoneNumbers.size() + 1;  // +1 for the header row.
        }

        @Override
        public ContactDetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            int layoutResId;
            switch (viewType) {
                case ID_HEADER:
                    layoutResId = R.layout.contact_detail_name_image;
                    break;
                case ID_CONTENT:
                    layoutResId = R.layout.contact_details_number;
                    break;
                default:
                    Log.e(TAG, "Unknown view type " + viewType);
                    return null;
            }

            View view = LayoutInflater.from(parent.getContext()).inflate(layoutResId, parent,
                    false);
            return new ContactDetailViewHolder(view);
        }

        @Override
        public void onBindViewHolder(ContactDetailViewHolder viewHolder, int position) {
            switch (viewHolder.getItemViewType()) {
                case ID_HEADER:
                    viewHolder.title.setText(mContactName);
                    if (!mPhoneNumbers.isEmpty()) {
                        String firstNumber = mPhoneNumbers.get(0).second;
                        TelecomUtils.setContactBitmapAsync(getContext(), viewHolder.avatar,
                                mContactName, firstNumber);
                    }
                    // Just in case a viewholder object gets recycled.
                    viewHolder.card.setOnClickListener(null);
                    break;
                case ID_CONTENT:
                    Pair<String, String> data = mPhoneNumbers.get(position - 1);
                    viewHolder.title.setText(data.second);  // Type.
                    viewHolder.text.setText(data.first);  // Number.
                    viewHolder.leftIcon.setImageResource(R.drawable.ic_phone);
                    viewHolder.leftIcon.setColorFilter(mIconTint);
                    viewHolder.card.setOnClickListener(v -> {
                        Intent callIntent = new Intent(Intent.ACTION_CALL);
                        callIntent.setData(Uri.parse(TELEPHONE_URI_PREFIX + data.second));
                        getContext().startActivity(callIntent);
                    });
                    break;
                default:
                    Log.e(TAG, "Unknown view type " + viewHolder.getItemViewType());
                    return;
            }

            if (position == (getItemCount() - 1)) {
                // hide divider for last item.
                viewHolder.divier.setVisibility(View.GONE);
            } else {
                viewHolder.divier.setVisibility(View.VISIBLE);
            }
            ListItemBackgroundResolver.setBackground(viewHolder.card,
                    viewHolder.getAdapterPosition(), getItemCount());
        }
    }
}
