package com.lemenzo.contacts;

import android.content.*;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.LruCache;
import android.util.Size;
import android.view.*;
import android.widget.*;

import java.util.*;
import java.util.concurrent.*;

public class ContactAdapter extends BaseAdapter {
    private final Context c;
    private List<ContactSummary> data = Collections.emptyList();
    private final ExecutorService imageIo = Executors.newFixedThreadPool(2, r -> {
        Thread t = new Thread(r, "LemenzoContacts-Thumb");
        t.setPriority(Thread.NORM_PRIORITY - 1);
        return t;
    });
    private final LruCache<String,Bitmap> imageCache = new LruCache<String,Bitmap>(8 * 1024 * 1024) {
        @Override protected int sizeOf(String key, Bitmap value) { return value.getAllocationByteCount(); }
    };
    private volatile boolean closed;

    private static final class Holder {
        final LinearLayout row;
        final FrameLayout avatarFrame;
        final TextView initials, name, phone;
        final ImageView photo, star;
        String imageToken;

        Holder(Context c) {
            row = Ui.card(c);
            row.setOrientation(LinearLayout.HORIZONTAL);
            row.setGravity(Gravity.CENTER_VERTICAL);

            avatarFrame = new FrameLayout(c);
            photo = new ImageView(c);
            photo.setScaleType(ImageView.ScaleType.CENTER_CROP);
            photo.setBackground(Ui.outline(c,Ui.SURFACE2,Ui.OUTLINE,24));
            photo.setClipToOutline(true);
            avatarFrame.addView(photo,new FrameLayout.LayoutParams(-1,-1));

            initials = Ui.title(c,"•",17);
            initials.setGravity(Gravity.CENTER);
            initials.setBackground(Ui.outline(c,Ui.SURFACE2,Ui.OUTLINE,24));
            avatarFrame.addView(initials,new FrameLayout.LayoutParams(-1,-1));
            row.addView(avatarFrame,new LinearLayout.LayoutParams(Ui.dp(c,48),Ui.dp(c,48)));

            LinearLayout txt=new LinearLayout(c);
            txt.setOrientation(LinearLayout.VERTICAL);
            txt.setPadding(Ui.dp(c,14),0,0,0);
            name=Ui.title(c,"",16);
            phone=Ui.text(c,"",13,Ui.SECONDARY);
            txt.addView(name);
            txt.addView(phone);
            row.addView(txt,new LinearLayout.LayoutParams(0,ViewGroup.LayoutParams.WRAP_CONTENT,1));

            star=new ImageView(c);
            star.setImageResource(R.drawable.ic_star);
            star.setContentDescription(c.getString(R.string.favorite));
            row.addView(star,new LinearLayout.LayoutParams(Ui.dp(c,28),Ui.dp(c,28)));
        }
    }

    public ContactAdapter(Context c){this.c=c;}
    public void setData(List<ContactSummary>d){data=d==null?Collections.emptyList():d;notifyDataSetChanged();}
    public int getCount(){return data.size();}
    public Object getItem(int p){return data.get(p);}
    public long getItemId(int p){return data.get(p).id;}

    @Override public View getView(int pos,View old,ViewGroup parent) {
        Holder h;
        if (old == null || !(old.getTag() instanceof Holder)) {
            h = new Holder(c);
            old = h.row;
            old.setTag(h);
        } else h = (Holder) old.getTag();

        ContactSummary x=data.get(pos);
        h.name.setText(x.name==null||x.name.isEmpty()?c.getString(R.string.unknown):x.name);
        h.phone.setText(x.phone==null?"":x.phone);
        h.phone.setVisibility(x.phone==null||x.phone.isEmpty()?View.GONE:View.VISIBLE);
        h.star.setVisibility(x.starred?View.VISIBLE:View.INVISIBLE);
        h.initials.setText(initials(x.name));
        h.initials.setVisibility(View.VISIBLE);
        h.photo.setImageDrawable(null);
        h.photo.setVisibility(View.GONE);

        String uri=x.photoUri==null?"":x.photoUri;
        h.imageToken=x.id+"|"+uri;
        if(!uri.isEmpty()) loadPhoto(h,uri,h.imageToken);
        return old;
    }

    private void loadPhoto(Holder h,String uri,String token) {
        Bitmap cached;
        synchronized(imageCache){ cached=imageCache.get(uri); }
        if(cached!=null){ applyPhoto(h,cached,token); return; }

        imageIo.execute(()->{
            if(closed)return;
            Bitmap b=null;
            try {
                b=c.getContentResolver().loadThumbnail(Uri.parse(uri),new Size(96,96),null);
            } catch(Exception ignored){}
            if(b==null||closed)return;
            synchronized(imageCache){ imageCache.put(uri,b); }
            Bitmap ready=b;
            h.row.post(()->applyPhoto(h,ready,token));
        });
    }

    private void applyPhoto(Holder h,Bitmap b,String token) {
        if(closed||!token.equals(h.imageToken))return;
        h.photo.setImageBitmap(b);
        h.photo.setVisibility(View.VISIBLE);
        h.initials.setVisibility(View.GONE);
    }

    public void close() {
        closed=true;
        imageIo.shutdownNow();
        synchronized(imageCache){ imageCache.evictAll(); }
    }

    private String initials(String s){
        if(s==null||s.trim().isEmpty())return "•";
        String[] p=s.trim().split("\\s+");
        String a=p[0].substring(0,1).toUpperCase();
        return p.length>1?a+p[p.length-1].substring(0,1).toUpperCase():a;
    }
}
