/*
 * Copyright (C) 2020 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.egg.neko;

import static com.android.egg.neko.NekoLand.CHAN_ID;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;

import com.android.egg.R;
import com.android.internal.logging.MetricsLogger;

import java.io.ByteArrayOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

/** It's a cat. */
public class Cat extends Drawable {
    public static final long[] PURR = {0, 40, 20, 40, 20, 40, 20, 40, 20, 40, 20, 40};

    public static final boolean ALL_CATS_IN_ONE_CONVERSATION = true;

    public static final String GLOBAL_SHORTCUT_ID = "com.android.egg.neko:allcats";
    public static final String SHORTCUT_ID_PREFIX = "com.android.egg.neko:cat:";

    private Random mNotSoRandom;
    private Bitmap mBitmap;
    private long mSeed;
    private String mName;
    private int mBodyColor;
    private int mFootType;
    private boolean mBowTie;
    private String mFirstMessage;

    private synchronized Random notSoRandom(long seed) {
        if (mNotSoRandom == null) {
            mNotSoRandom = new Random();
            mNotSoRandom.setSeed(seed);
        }
        return mNotSoRandom;
    }

    public static final float frandrange(Random r, float a, float b) {
        return (b - a) * r.nextFloat() + a;
    }

    public static final Object choose(Random r, Object... l) {
        return l[r.nextInt(l.length)];
    }

    public static final int chooseP(Random r, int[] a) {
        return chooseP(r, a, 1000);
    }

    public static final int chooseP(Random r, int[] a, int sum) {
        int pct = r.nextInt(sum);
        final int stop = a.length - 2;
        int i = 0;
        while (i < stop) {
            pct -= a[i];
            if (pct < 0) break;
            i += 2;
        }
        return a[i + 1];
    }

    public static final int getColorIndex(int q, int[] a) {
        for (int i = 1; i < a.length; i += 2) {
            if (a[i] == q) {
                return i / 2;
            }
        }
        return -1;
    }

    public static final int[] P_BODY_COLORS = {
            180, 0xFF212121, // black
            180, 0xFFFFFFFF, // white
            140, 0xFF616161, // gray
            140, 0xFF795548, // brown
            100, 0xFF90A4AE, // steel
            100, 0xFFFFF9C4, // buff
            100, 0xFFFF8F00, // orange
            5, 0xFF29B6F6, // blue..?
            5, 0xFFFFCDD2, // pink!?
            5, 0xFFCE93D8, // purple?!?!?
            4, 0xFF43A047, // yeah, why not green
            1, 0,          // ?!?!?!
    };

    public static final int[] P_COLLAR_COLORS = {
            250, 0xFFFFFFFF,
            250, 0xFF000000,
            250, 0xFFF44336,
            50, 0xFF1976D2,
            50, 0xFFFDD835,
            50, 0xFFFB8C00,
            50, 0xFFF48FB1,
            50, 0xFF4CAF50,
    };

    public static final int[] P_BELLY_COLORS = {
            750, 0,
            250, 0xFFFFFFFF,
    };

    public static final int[] P_DARK_SPOT_COLORS = {
            700, 0,
            250, 0xFF212121,
            50, 0xFF6D4C41,
    };

    public static final int[] P_LIGHT_SPOT_COLORS = {
            700, 0,
            300, 0xFFFFFFFF,
    };

    private CatParts D;

    public static void tint(int color, Drawable... ds) {
        for (Drawable d : ds) {
            if (d != null) {
                d.mutate().setTint(color);
            }
        }
    }

    public static boolean isDark(int color) {
        final int r = (color & 0xFF0000) >> 16;
        final int g = (color & 0x00FF00) >> 8;
        final int b = color & 0x0000FF;
        return (r + g + b) < 0x80;
    }

    public Cat(Context context, long seed) {
        D = new CatParts(context);
        mSeed = seed;

        setName(context.getString(R.string.default_cat_name,
                String.valueOf(mSeed % 1000)));

        final Random nsr = notSoRandom(seed);

        // body color
        mBodyColor = chooseP(nsr, P_BODY_COLORS);
        if (mBodyColor == 0) mBodyColor = Color.HSVToColor(new float[]{
                nsr.nextFloat() * 360f, frandrange(nsr, 0.5f, 1f), frandrange(nsr, 0.5f, 1f)});

        tint(mBodyColor, D.body, D.head, D.leg1, D.leg2, D.leg3, D.leg4, D.tail,
                D.leftEar, D.rightEar, D.foot1, D.foot2, D.foot3, D.foot4, D.tailCap);
        tint(0x20000000, D.leg2Shadow, D.tailShadow);
        if (isDark(mBodyColor)) {
            tint(0xFFFFFFFF, D.leftEye, D.rightEye, D.mouth, D.nose);
        }
        tint(isDark(mBodyColor) ? 0xFFEF9A9A : 0x20D50000, D.leftEarInside, D.rightEarInside);

        tint(chooseP(nsr, P_BELLY_COLORS), D.belly);
        tint(chooseP(nsr, P_BELLY_COLORS), D.back);
        final int faceColor = chooseP(nsr, P_BELLY_COLORS);
        tint(faceColor, D.faceSpot);
        if (!isDark(faceColor)) {
            tint(0xFF000000, D.mouth, D.nose);
        }

        mFootType = 0;
        if (nsr.nextFloat() < 0.25f) {
            mFootType = 4;
            tint(0xFFFFFFFF, D.foot1, D.foot2, D.foot3, D.foot4);
        } else {
            if (nsr.nextFloat() < 0.25f) {
                mFootType = 2;
                tint(0xFFFFFFFF, D.foot1, D.foot3);
            } else if (nsr.nextFloat() < 0.25f) {
                mFootType = 3; // maybe -2 would be better? meh.
                tint(0xFFFFFFFF, D.foot2, D.foot4);
            } else if (nsr.nextFloat() < 0.1f) {
                mFootType = 1;
                tint(0xFFFFFFFF, (Drawable) choose(nsr, D.foot1, D.foot2, D.foot3, D.foot4));
            }
        }

        tint(nsr.nextFloat() < 0.333f ? 0xFFFFFFFF : mBodyColor, D.tailCap);

        final int capColor = chooseP(nsr, isDark(mBodyColor) ? P_LIGHT_SPOT_COLORS : P_DARK_SPOT_COLORS);
        tint(capColor, D.cap);
        //tint(chooseP(nsr, isDark(bodyColor) ? P_LIGHT_SPOT_COLORS : P_DARK_SPOT_COLORS), D.nose);

        final int collarColor = chooseP(nsr, P_COLLAR_COLORS);
        tint(collarColor, D.collar);
        mBowTie = nsr.nextFloat() < 0.1f;
        tint(mBowTie ? collarColor : 0, D.bowtie);

        String[] messages = context.getResources().getStringArray(
                nsr.nextFloat() < 0.1f ? R.array.rare_cat_messages : R.array.cat_messages);
        mFirstMessage = (String) choose(nsr, (Object[]) messages);
        if (nsr.nextFloat() < 0.5f) mFirstMessage = mFirstMessage + mFirstMessage + mFirstMessage;
    }

    public static Cat fromShortcutId(Context context, String shortcutId) {
        if (shortcutId.startsWith(SHORTCUT_ID_PREFIX)) {
            return new Cat(context, Long.parseLong(shortcutId.replace(SHORTCUT_ID_PREFIX, "")));
        }
        return null;
    }

    public static Cat create(Context context) {
        return new Cat(context, Math.abs(ThreadLocalRandom.current().nextInt()));
    }

    public Notification.Builder buildNotification(Context context) {
        final Bundle extras = new Bundle();
        extras.putString("android.substName", context.getString(R.string.notification_name));

        final Icon notificationIcon = createNotificationLargeIcon(context);

        final Intent intent = new Intent(Intent.ACTION_MAIN)
                .setClass(context, NekoLand.class)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        ShortcutInfo shortcut = new ShortcutInfo.Builder(context, getShortcutId())
                .setActivity(intent.getComponent())
                .setIntent(intent)
                .setShortLabel(getName())
                .setIcon(createShortcutIcon(context))
                .setLongLived(true)
                .build();
        context.getSystemService(ShortcutManager.class).addDynamicShortcuts(List.of(shortcut));

        Notification.BubbleMetadata bubbs = new Notification.BubbleMetadata.Builder()
                .setIntent(
                        PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE))
                .setIcon(notificationIcon)
                .setSuppressNotification(false)
                .setDesiredHeight(context.getResources().getDisplayMetrics().heightPixels)
                .build();

        return new Notification.Builder(context, CHAN_ID)
                .setSmallIcon(Icon.createWithResource(context, R.drawable.stat_icon))
                .setLargeIcon(notificationIcon)
                .setColor(getBodyColor())
                .setContentTitle(context.getString(R.string.notification_title))
                .setShowWhen(true)
                .setCategory(Notification.CATEGORY_STATUS)
                .setContentText(getName())
                .setContentIntent(
                        PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE))
                .setAutoCancel(true)
                .setStyle(new Notification.MessagingStyle(createPerson())
                        .addMessage(mFirstMessage, System.currentTimeMillis(), createPerson())
                        .setConversationTitle(getName())
                )
                .setBubbleMetadata(bubbs)
                .setShortcutId(getShortcutId())
                .addExtras(extras);
    }

    private Person createPerson() {
        return new Person.Builder()
                .setName(getName())
                .setBot(true)
                .setKey(getShortcutId())
                .build();
    }

    public long getSeed() {
        return mSeed;
    }

    @Override
    public void draw(Canvas canvas) {
        final int w = Math.min(canvas.getWidth(), canvas.getHeight());
        final int h = w;

        if (mBitmap == null || mBitmap.getWidth() != w || mBitmap.getHeight() != h) {
            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            final Canvas bitCanvas = new Canvas(mBitmap);
            slowDraw(bitCanvas, 0, 0, w, h);
        }
        canvas.drawBitmap(mBitmap, 0, 0, null);
    }

    private void slowDraw(Canvas canvas, int x, int y, int w, int h) {
        for (int i = 0; i < D.drawingOrder.length; i++) {
            final Drawable d = D.drawingOrder[i];
            if (d != null) {
                d.setBounds(x, y, x + w, y + h);
                d.draw(canvas);
            }
        }

    }

    public Bitmap createBitmap(int w, int h) {
        if (mBitmap != null && mBitmap.getWidth() == w && mBitmap.getHeight() == h) {
            return mBitmap.copy(mBitmap.getConfig(), true);
        }
        Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        slowDraw(new Canvas(result), 0, 0, w, h);
        return result;
    }

    public static Icon recompressIcon(Icon bitmapIcon) {
        if (bitmapIcon.getType() != Icon.TYPE_BITMAP) return bitmapIcon;
        try {
            final Bitmap bits = (Bitmap) Icon.class.getDeclaredMethod("getBitmap").invoke(bitmapIcon);
            final ByteArrayOutputStream ostream = new ByteArrayOutputStream(
                    bits.getWidth() * bits.getHeight() * 2); // guess 50% compression
            final boolean ok = bits.compress(Bitmap.CompressFormat.PNG, 100, ostream);
            if (!ok) return null;
            return Icon.createWithData(ostream.toByteArray(), 0, ostream.size());
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
            return bitmapIcon;
        }
    }

    public Icon createNotificationLargeIcon(Context context) {
        final Resources res = context.getResources();
        final int w = res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
        final int h = res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
        return recompressIcon(createIcon(context, w, h));
    }

    public Icon createShortcutIcon(Context context) {
        // shortcuts do not support compressed bitmaps
        final Resources res = context.getResources();
        final int w = res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
        final int h = res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
        return createIcon(context, w, h);
    }

    public Icon createIcon(Context context, int w, int h) {
        Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(result);
        float[] hsv = new float[3];
        Color.colorToHSV(mBodyColor, hsv);
        hsv[2] = (hsv[2] > 0.5f)
                ? (hsv[2] - 0.25f)
                : (hsv[2] + 0.25f);
        //final Paint pt = new Paint();
        //pt.setColor(Color.HSVToColor(hsv));
        //float r = w/2;
        //canvas.drawCircle(r, r, r, pt);
        // int m = w/10;

        // Adaptive bitmaps!
        canvas.drawColor(Color.HSVToColor(hsv));
        int m = w / 4;

        slowDraw(canvas, m, m, w - m - m, h - m - m);

        return Icon.createWithAdaptiveBitmap(result);
    }

    @Override
    public void setAlpha(int i) {

    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        this.mName = name;
    }

    public int getBodyColor() {
        return mBodyColor;
    }

    public void logAdd(Context context) {
        logCatAction(context, "egg_neko_add");
    }

    public void logRename(Context context) {
        logCatAction(context, "egg_neko_rename");
    }

    public void logRemove(Context context) {
        logCatAction(context, "egg_neko_remove");
    }

    public void logShare(Context context) {
        logCatAction(context, "egg_neko_share");
    }

    private void logCatAction(Context context, String prefix) {
        MetricsLogger.count(context, prefix, 1);
        MetricsLogger.histogram(context, prefix + "_color",
                getColorIndex(mBodyColor, P_BODY_COLORS));
        MetricsLogger.histogram(context, prefix + "_bowtie", mBowTie ? 1 : 0);
        MetricsLogger.histogram(context, prefix + "_feet", mFootType);
    }

    public String getShortcutId() {
        return ALL_CATS_IN_ONE_CONVERSATION
                ? GLOBAL_SHORTCUT_ID
                : (SHORTCUT_ID_PREFIX + mSeed);
    }

    public static class CatParts {
        public Drawable leftEar;
        public Drawable rightEar;
        public Drawable rightEarInside;
        public Drawable leftEarInside;
        public Drawable head;
        public Drawable faceSpot;
        public Drawable cap;
        public Drawable mouth;
        public Drawable body;
        public Drawable foot1;
        public Drawable leg1;
        public Drawable foot2;
        public Drawable leg2;
        public Drawable foot3;
        public Drawable leg3;
        public Drawable foot4;
        public Drawable leg4;
        public Drawable tail;
        public Drawable leg2Shadow;
        public Drawable tailShadow;
        public Drawable tailCap;
        public Drawable belly;
        public Drawable back;
        public Drawable rightEye;
        public Drawable leftEye;
        public Drawable nose;
        public Drawable bowtie;
        public Drawable collar;
        public Drawable[] drawingOrder;

        public CatParts(Context context) {
            body = context.getDrawable(R.drawable.body);
            head = context.getDrawable(R.drawable.head);
            leg1 = context.getDrawable(R.drawable.leg1);
            leg2 = context.getDrawable(R.drawable.leg2);
            leg3 = context.getDrawable(R.drawable.leg3);
            leg4 = context.getDrawable(R.drawable.leg4);
            tail = context.getDrawable(R.drawable.tail);
            leftEar = context.getDrawable(R.drawable.left_ear);
            rightEar = context.getDrawable(R.drawable.right_ear);
            rightEarInside = context.getDrawable(R.drawable.right_ear_inside);
            leftEarInside = context.getDrawable(R.drawable.left_ear_inside);
            faceSpot = context.getDrawable(R.drawable.face_spot);
            cap = context.getDrawable(R.drawable.cap);
            mouth = context.getDrawable(R.drawable.mouth);
            foot4 = context.getDrawable(R.drawable.foot4);
            foot3 = context.getDrawable(R.drawable.foot3);
            foot1 = context.getDrawable(R.drawable.foot1);
            foot2 = context.getDrawable(R.drawable.foot2);
            leg2Shadow = context.getDrawable(R.drawable.leg2_shadow);
            tailShadow = context.getDrawable(R.drawable.tail_shadow);
            tailCap = context.getDrawable(R.drawable.tail_cap);
            belly = context.getDrawable(R.drawable.belly);
            back = context.getDrawable(R.drawable.back);
            rightEye = context.getDrawable(R.drawable.right_eye);
            leftEye = context.getDrawable(R.drawable.left_eye);
            nose = context.getDrawable(R.drawable.nose);
            collar = context.getDrawable(R.drawable.collar);
            bowtie = context.getDrawable(R.drawable.bowtie);
            drawingOrder = getDrawingOrder();
        }

        private Drawable[] getDrawingOrder() {
            return new Drawable[]{
                    collar,
                    leftEar, leftEarInside, rightEar, rightEarInside,
                    head,
                    faceSpot,
                    cap,
                    leftEye, rightEye,
                    nose, mouth,
                    tail, tailCap, tailShadow,
                    foot1, leg1,
                    foot2, leg2,
                    foot3, leg3,
                    foot4, leg4,
                    leg2Shadow,
                    body, belly,
                    bowtie
            };
        }
    }
}
