/*
 * Copyright (C) 2015 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.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.PorterDuff;
import android.os.Handler;
import android.provider.CallLog;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.car.widget.PagedListView;

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**
 * Adapter class for populating Contact data as loaded from the DB to an AA GroupingRecyclerView.
 * It handles two types of contacts:
 * <p>
 * <ul>
 * <li>Strequent contacts (starred and/or frequent)
 * <li>Last call contact
 * </ul>
 */
public class StrequentsAdapter extends RecyclerView.Adapter<CallLogViewHolder>
        implements PagedListView.ItemCap {
    // The possible view types in this adapter.
    private static final int VIEW_TYPE_EMPTY = 0;
    private static final int VIEW_TYPE_LASTCALL = 1;
    private static final int VIEW_TYPE_STREQUENT = 2;
    private static final long LAST_CALL_REFRESH_INTERVAL_MILLIS = 60 * 1000L;

    private final Context mContext;
    private final UiCallManager mUiCallManager;
    private List<ContactEntry> mData;
    private Handler mMainThreadHandler = new Handler();

    private LastCallData mLastCallData;
    private Cursor mLastCallCursor;
    private LastCallPeriodicalUpdater mLastCallPeriodicalUpdater = new LastCallPeriodicalUpdater();

    private final ContentResolver mContentResolver;

    public interface StrequentsListener<T> {
        /** Notified when a row corresponding an individual Contact (not group) was clicked. */
        void onContactClicked(T viewHolder);
    }

    private View.OnFocusChangeListener mFocusChangeListener;
    private StrequentsListener<CallLogViewHolder> mStrequentsListener;

    private int mMaxItems = -1;
    private boolean mIsEmpty;

    public StrequentsAdapter(Context context, UiCallManager callManager) {
        mContext = context;
        mUiCallManager = callManager;
        mContentResolver = context.getContentResolver();
    }

    public void setStrequentsListener(@Nullable StrequentsListener<CallLogViewHolder> listener) {
        mStrequentsListener = listener;
    }

    public void setLastCallCursor(@Nullable Cursor cursor) {
        mLastCallCursor = cursor;
        mLastCallData = convertLastCallCursor(cursor);
        if (cursor != null) {
            mMainThreadHandler.postDelayed(mLastCallPeriodicalUpdater,
                    LAST_CALL_REFRESH_INTERVAL_MILLIS);
        } else {
            mMainThreadHandler.removeCallbacks(mLastCallPeriodicalUpdater);
        }

        notifyDataSetChanged();
    }

    public void setStrequentCursor(@Nullable Cursor cursor) {
        if (cursor != null) {
            setData(convertStrequentCursorToArray(cursor));
        } else {
            setData(null);
        }
        notifyDataSetChanged();
    }

    private void setData(List<ContactEntry> data) {
        mData = data;
        notifyDataSetChanged();
    }

    @Override
    public void setMaxItems(int maxItems) {
        mMaxItems = maxItems;
    }

    @Override
    public int getItemViewType(int position) {
        if (mIsEmpty) {
            return VIEW_TYPE_EMPTY;
        } else if (position == 0 && mLastCallData != null) {
            return VIEW_TYPE_LASTCALL;
        } else {
            return VIEW_TYPE_STREQUENT;
        }
    }

    @Override
    public int getItemCount() {
        int itemCount = mData == null ? 0 : mData.size();
        itemCount += mLastCallData == null ? 0 : 1;

        mIsEmpty = itemCount == 0;

        // If there is no data to display, add one to the item count to display the card in the
        // empty state.
        if (mIsEmpty) {
            itemCount++;
        }

        return mMaxItems >= 0 ? Math.min(mMaxItems, itemCount) : itemCount;
    }

    @Override
    public CallLogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case VIEW_TYPE_EMPTY:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.call_log_list_item_empty, parent, false);
                return new CallLogViewHolder(view);

            case VIEW_TYPE_LASTCALL:
            case VIEW_TYPE_STREQUENT:
            default:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.call_log_list_item_card, parent, false);
                return new CallLogViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(final CallLogViewHolder viewHolder, int position) {
        switch (viewHolder.getItemViewType()) {
            case VIEW_TYPE_LASTCALL:
                onBindLastCallRow(viewHolder);
                break;

            case VIEW_TYPE_EMPTY:
                viewHolder.icon.setImageResource(R.drawable.ic_empty_speed_dial);
                viewHolder.title.setText(R.string.speed_dial_empty);
                viewHolder.title.setTextColor(mContext.getColor(R.color.car_body1_light));
                break;

            case VIEW_TYPE_STREQUENT:
            default:
                int positionIntoData = position;

                // If there is last call data, then decrement the position so there is not an out of
                // bounds error on the mData.
                if (mLastCallData != null) {
                    positionIntoData--;
                }

                onBindView(viewHolder, mData.get(positionIntoData));
                viewHolder.callType.setVisibility(View.VISIBLE);
        }
    }

    private void onViewClicked(CallLogViewHolder viewHolder) {
        if (mStrequentsListener != null) {
            mStrequentsListener.onContactClicked(viewHolder);
        }
    }

    @Override
    public void onViewAttachedToWindow(CallLogViewHolder holder) {
        if (mFocusChangeListener != null) {
            holder.itemView.setOnFocusChangeListener(mFocusChangeListener);
        }
    }

    @Override
    public void onViewDetachedFromWindow(CallLogViewHolder holder) {
        holder.itemView.setOnFocusChangeListener(null);
    }

    /**
     * Converts the strequents data in the given cursor into a list of {@link ContactEntry}s.
     */
    private List<ContactEntry> convertStrequentCursorToArray(Cursor cursor) {
        List<ContactEntry> strequentContactEntries = new ArrayList<>();
        HashMap<Integer, ContactEntry> entryMap = new HashMap<>();
        cursor.moveToPosition(-1);

        while (cursor.moveToNext()) {
            final ContactEntry entry = ContactEntry.fromCursor(cursor, mContext);
            entryMap.put(entry.hashCode(), entry);
        }

        strequentContactEntries.addAll(entryMap.values());
        Collections.sort(strequentContactEntries);
        return strequentContactEntries;
    }

    /**
     * Binds the views in the entry to the data of last call.
     *
     * @param viewHolder the view holder corresponding to this entry
     */
    private void onBindLastCallRow(final CallLogViewHolder viewHolder) {
        if (mLastCallData == null) {
            return;
        }

        viewHolder.itemView.setOnClickListener(v -> onViewClicked(viewHolder));

        String primaryText = mLastCallData.getPrimaryText();
        String number = mLastCallData.getNumber();

        if (!number.equals(viewHolder.itemView.getTag())) {
            viewHolder.title.setText(mLastCallData.getPrimaryText());
            viewHolder.itemView.setTag(number);
            viewHolder.callTypeIconsView.clear();
            viewHolder.callTypeIconsView.setVisibility(View.VISIBLE);

            // mHasFirstItem is true only in main screen, or else it is in drawer, then we need
            // to add
            // call type icons for call history items.
            viewHolder.smallIcon.setVisibility(View.GONE);
            int[] callTypes = mLastCallData.getCallTypes();
            int icons = Math.min(callTypes.length, CallTypeIconsView.MAX_CALL_TYPE_ICONS);
            for (int i = 0; i < icons; i++) {
                viewHolder.callTypeIconsView.add(callTypes[i]);
            }

            TelecomUtils.setContactBitmapAsync(mContext, viewHolder.icon, primaryText, number);
        }

        viewHolder.text.setText(mLastCallData.getSecondaryText());
    }

    /**
     * Converts the last call information in the given cursor into a {@link LastCallData} object
     * so that the cursor can be closed.
     *
     * @return A valid {@link LastCallData} or {@code null} if the cursor is {@code null} or has no
     * data in it.
     */
    @Nullable
    public LastCallData convertLastCallCursor(@Nullable Cursor cursor) {
        if (cursor == null || cursor.getCount() == 0) {
            return null;
        }

        cursor.moveToFirst();

        final StringBuilder nameSb = new StringBuilder();
        int column = PhoneLoader.getNameColumnIndex(cursor);
        String cachedName = cursor.getString(column);
        final String number = PhoneLoader.getPhoneNumber(cursor, mContentResolver);
        if (cachedName == null) {
            cachedName = TelecomUtils.getDisplayName(mContext, number);
        }

        boolean isVoicemail = false;
        if (cachedName == null) {
            if (number.equals(TelecomUtils.getVoicemailNumber(mContext))) {
                isVoicemail = true;
                nameSb.append(mContext.getString(R.string.voicemail));
            } else {
                String displayName = TelecomUtils.getFormattedNumber(mContext, number);
                if (TextUtils.isEmpty(displayName)) {
                    displayName = mContext.getString(R.string.unknown);
                }
                nameSb.append(displayName);
            }
        } else {
            nameSb.append(cachedName);
        }
        column = cursor.getColumnIndex(CallLog.Calls.DATE);
        // If we set this to 0, getRelativeTime will return null and no relative time
        // will be displayed.
        long millis = column == -1 ? 0 : cursor.getLong(column);
        StringBuilder secondaryText = new StringBuilder();
        CharSequence relativeDate = getRelativeTime(millis);
        if (!isVoicemail) {
            CharSequence type = TelecomUtils.getTypeFromNumber(mContext, number);
            secondaryText.append(type);
            if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(relativeDate)) {
                secondaryText.append(", ");
            }
        }
        if (relativeDate != null) {
            secondaryText.append(relativeDate);
        }

        int[] callTypes = mUiCallManager.getCallTypes(cursor, 1);

        return new LastCallData(number, nameSb.toString(), secondaryText.toString(), callTypes);
    }

    /**
     * Bind view function for frequent call row.
     */
    private void onBindView(final CallLogViewHolder viewHolder, final ContactEntry entry) {
        viewHolder.itemView.setOnClickListener(v -> onViewClicked(viewHolder));

        final String number = entry.getNumber();
        // TODO: Why is being a voicemail related to not having a name?
        boolean isVoicemail = entry.isVoicemail();
        String secondaryText = "";
        if (!isVoicemail) {
            secondaryText = String.valueOf(TelecomUtils.getTypeFromNumber(mContext, number));
        }

        viewHolder.text.setText(secondaryText);
        viewHolder.itemView.setTag(number);
        viewHolder.callTypeIconsView.clear();

        String displayName = entry.getDisplayName();
        viewHolder.title.setText(displayName);

        TelecomUtils.setContactBitmapAsync(mContext, viewHolder.icon, displayName, number);

        if (entry.isStarred()) {
            viewHolder.smallIcon.setVisibility(View.VISIBLE);
            final int iconColor = mContext.getColor(android.R.color.white);
            viewHolder.smallIcon.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
            viewHolder.smallIcon.setImageResource(R.drawable.ic_favorite);
        } else {
            viewHolder.smallIcon.setVisibility(View.GONE);
        }

    }

    /**
     * Build any timestamp and label into a single string. If the given timestamp is invalid, then
     * {@code null} is returned.
     */
    @Nullable
    private static CharSequence getRelativeTime(long millis) {
        if (millis <= 0) {
            return null;
        }

        return DateUtils.getRelativeTimeSpanString(millis, System.currentTimeMillis(),
                DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE);
    }

    /**
     * A container for data relating to a last call entry.
     */
    private class LastCallData {
        private final String mNumber;
        private final String mPrimaryText;
        private final String mSecondaryText;
        private final int[] mCallTypes;

        LastCallData(String number, String primaryText, String secondaryText,
                int[] callTypes) {
            mNumber = number;
            mPrimaryText = primaryText;
            mSecondaryText = secondaryText;
            mCallTypes = callTypes;
        }

        public String getNumber() {
            return mNumber;
        }

        public String getPrimaryText() {
            return mPrimaryText;
        }

        public String getSecondaryText() {
            return mSecondaryText;
        }

        public int[] getCallTypes() {
            return mCallTypes;
        }
    }

    private class LastCallPeriodicalUpdater implements Runnable {

        @Override
        public void run() {
            mLastCallData = convertLastCallCursor(mLastCallCursor);
            notifyItemChanged(0);
            mMainThreadHandler.postDelayed(this, LAST_CALL_REFRESH_INTERVAL_MILLIS);
        }
    }
}
