package com.wytehat.btlogger;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class DeviceListAdapter extends BaseAdapter {
    private final Context context;
    private List<DeviceRecord> rows;
    private final ItemActionListener listener;

    public DeviceListAdapter(Context context, List<DeviceRecord> rows,
                             ItemActionListener listener) {
        this.context = context;
        this.rows = rows;
        this.listener = listener;
    }

    public void setRows(List<DeviceRecord> value) {
        rows = value;
        notifyDataSetChanged();
    }

    public int getCount() { return rows.size(); }
    public Object getItem(int position) { return rows.get(position); }
    public long getItemId(int position) { return position; }

    public View getView(int position, View oldView, ViewGroup parent) {
        View view = oldView;
        if (view == null) view = LayoutInflater.from(context).inflate(
            R.layout.device_row, parent, false);
        final DeviceRecord record = rows.get(position);
        ImageView image = (ImageView) view.findViewById(R.id.item_image);
        if (record.photoUri != null && new java.io.File(record.photoUri).exists()) {
            image.setImageBitmap(BitmapFactory.decodeFile(record.photoUri));
        } else image.setImageResource(icon(record.iconPreset));

        ((TextView) view.findViewById(R.id.device_title)).setText(
            record.displayName() + "\n" + record.address);
        TextView vendor = (TextView) view.findViewById(R.id.device_vendor);
        vendor.setText(record.vendorName == null ? "Manufacturer unknown" : record.vendorName);
        vendor.setVisibility(record.vendorName == null || record.vendorName.length() == 0 ? View.GONE : View.VISIBLE);
        boolean recentSignal = record.rssi != 0 && record.lastRssiAt > 0 &&
            System.currentTimeMillis() - record.lastRssiAt <= 120000L;
        boolean broadcastFresh = record.rssi != 0 && record.lastRssiAt > 0 &&
            System.currentTimeMillis() - record.lastRssiAt <= 180000L;
        String seenState;
        if (record.connected == 1) seenState = "● Nearby / Connected";
        else if (recentSignal) seenState = "● Broadcasting now  •  Seen " + date(record.lastRssiAt);
        else if (record.updatedAt <= 0) seenState = "Paired / saved — never seen";
        else seenState = "Last seen " + date(record.updatedAt);
        ((TextView) view.findViewById(R.id.device_state)).setText(seenState);
        ((TextView) view.findViewById(R.id.device_telemetry)).setText(
            "Battery " + (record.battery < 0 ? "—" : record.battery + "%") +
            "   Signal " + signal(record.rssi));
        TextView reason = (TextView) view.findViewById(R.id.device_reason);
        String configuredPolling = record.trackingPriority > 0
            ? "GPS every " + record.trackingPriority + " min" : "GPS event-only";
        String polling;
        if (record.connected == 1) polling = configuredPolling + " while connected";
        else if (record.trackBroadcast == 1 && broadcastFresh) polling = configuredPolling + " while broadcasting";
        else if (record.trackBroadcast == 1) polling = configuredPolling + " • waiting for broadcast";
        else polling = configuredPolling + " • paused — not connected";
        reason.setText((record.connected == 1 ? "With you" : (record.updatedAt <= 0 ? "Not yet observed" : shortReason(record.reason))) +
            "   •   " + polling + "   •   Pin " + record.pinColor);
        try { reason.setTextColor(Color.parseColor(record.pinColor)); }
        catch (Exception ignored) { reason.setTextColor(Color.DKGRAY); }

        Button map = (Button) view.findViewById(R.id.map_button);
        map.setEnabled(record.hasLocation);
        map.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { listener.map(record); }
        });
        View liveButton = view.findViewById(R.id.live_find_button);
        boolean liveAvailable = recentSignal;
        liveButton.setVisibility(liveAvailable ? View.VISIBLE : View.GONE);
        view.findViewById(R.id.live_find_button).setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { listener.live(record); }
        });
        view.findViewById(R.id.manage_button).setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { listener.manage(record); }
        });
        view.findViewById(R.id.edit_button).setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { listener.edit(record); }
        });
        return view;
    }

    private int icon(String value) {
        if ("headphones".equals(value)) return android.R.drawable.ic_media_play;
        if ("keys".equals(value)) return android.R.drawable.ic_lock_lock;
        if ("car".equals(value)) return android.R.drawable.ic_menu_directions;
        if ("wallet".equals(value)) return android.R.drawable.ic_menu_agenda;
        return android.R.drawable.ic_menu_myplaces;
    }

    private String signal(int value) {
        if (value == 0) return "—";
        if (value >= -65) return "Strong (" + value + " dBm)";
        if (value >= -80) return "Medium (" + value + " dBm)";
        return "Weak (" + value + " dBm)";
    }

    private String date(long time) {
        return time <= 0 ? "never" : DateFormat.getDateTimeInstance(
            DateFormat.SHORT, DateFormat.SHORT).format(new Date(time));
    }

    private String shortReason(String value) {
        if (value == null) return "Status unknown";
        if (value.indexOf("Range") >= 0) return "Out of range";
        if (value.indexOf("Battery") >= 0 || value.indexOf("Power") >= 0)
            return "Possible dead battery";
        return value;
    }
}
