package com.example.petstoremobile.adapters;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.bumptech.glide.signature.ObjectKey;
import com.example.petstoremobile.R;
import com.example.petstoremobile.databinding.ItemMessageReceivedBinding;
import com.example.petstoremobile.databinding.ItemMessageSentBinding;
import com.example.petstoremobile.models.Message;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int TYPE_SENT = 1;
    private static final int TYPE_RECEIVED = 2;

    public interface OnAttachmentClickListener {
        void onAttachmentClick(Message message);
    }

    private final List<Message> messages;
    private Long currentUserId;
    private Long staffId;
    private String token;
    private String baseUrl;
    private OnAttachmentClickListener attachmentClickListener;

    public MessageAdapter(List<Message> messages, Long currentUserId) {
        this.messages = messages;
        this.currentUserId = currentUserId;
        setHasStableIds(true);
    }

    @Override
    public long getItemId(int position) {
        Message m = messages.get(position);
        return m.getId() != null ? m.getId() : position;
    }

    public void setCurrentUserId(Long id) {
        this.currentUserId = id;
        notifyDataSetChanged();
    }

    public void setStaffId(Long id) {
        this.staffId = id;
        notifyDataSetChanged();
    }

    public void setToken(String token) {
        this.token = token;
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public void setOnAttachmentClickListener(OnAttachmentClickListener listener) {
        this.attachmentClickListener = listener;
    }

    @Override
    public int getItemViewType(int position) {
        Message m = messages.get(position);
        if (currentUserId != null && currentUserId.equals(m.getSenderId())) {
            return TYPE_SENT;
        }
        return TYPE_RECEIVED;
    }

    @NonNull @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inf = LayoutInflater.from(parent.getContext());
        if (viewType == TYPE_SENT) {
            ItemMessageSentBinding binding = ItemMessageSentBinding.inflate(inf, parent, false);
            return new SentHolder(binding);
        } else {
            ItemMessageReceivedBinding binding = ItemMessageReceivedBinding.inflate(inf, parent, false);
            return new ReceivedHolder(binding);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        Message m = messages.get(position);
        if (holder instanceof SentHolder)     ((SentHolder) holder).bind(m, token, baseUrl, attachmentClickListener);
        if (holder instanceof ReceivedHolder) ((ReceivedHolder) holder).bind(m, token, baseUrl, attachmentClickListener, staffId);
    }

    @Override public int getItemCount() { return messages.size(); }

    static class SentHolder extends RecyclerView.ViewHolder {
        final ItemMessageSentBinding binding;
        SentHolder(ItemMessageSentBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
        void bind(Message m, String token, String baseUrl, OnAttachmentClickListener listener) {
            binding.tvSenderName.setText("You");
            binding.tvTimestamp.setText(formatTimestamp(m.getTimestamp()));

            if (m.getContent() != null && !m.getContent().isEmpty()) {
                binding.tvMessageContent.setVisibility(View.VISIBLE);
                binding.tvMessageContent.setText(m.getContent());
            } else {
                binding.tvMessageContent.setVisibility(View.GONE);
            }

            displayAttachment(m, binding.ivAttachment, binding.tvAttachmentName, token, baseUrl);

            View.OnClickListener click = v -> {
                if (listener != null) listener.onAttachmentClick(m);
            };
            binding.ivAttachment.setOnClickListener(click);
            binding.tvAttachmentName.setOnClickListener(click);
        }
    }

    static class ReceivedHolder extends RecyclerView.ViewHolder {
        final ItemMessageReceivedBinding binding;
        ReceivedHolder(ItemMessageReceivedBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
        void bind(Message m, String token, String baseUrl, OnAttachmentClickListener listener, Long staffId) {
            binding.tvSenderName.setText(resolveSenderName(m, staffId));
            binding.tvTimestamp.setText(formatTimestamp(m.getTimestamp()));

            if (m.getContent() != null && !m.getContent().isEmpty()) {
                binding.tvMessageContent.setVisibility(View.VISIBLE);
                binding.tvMessageContent.setText(m.getContent());
            } else {
                binding.tvMessageContent.setVisibility(View.GONE);
            }

            displayAttachment(m, binding.ivAttachment, binding.tvAttachmentName, token, baseUrl);

            View.OnClickListener click = v -> {
                if (listener != null) listener.onAttachmentClick(m);
            };
            binding.ivAttachment.setOnClickListener(click);
            binding.tvAttachmentName.setOnClickListener(click);
        }
    }

    private static String resolveSenderName(Message m, Long staffId) {
        if ("BOT".equalsIgnoreCase(m.getSenderRole())) {
            return (m.getSenderDisplayName() != null && !m.getSenderDisplayName().isEmpty())
                    ? m.getSenderDisplayName() : "AI Bot";
        }
        if (staffId != null && staffId.equals(m.getSenderId())) {
            return "Staff";
        }
        return "Customer";
    }

    private static String formatTimestamp(String timestamp) {
        if (timestamp == null || timestamp.isEmpty()) return "";
        try {
            String normalized = timestamp.length() > 19 ? timestamp.substring(0, 19) : timestamp;
            SimpleDateFormat input = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
            Date date = input.parse(normalized);
            return new SimpleDateFormat("MMM d, HH:mm", Locale.getDefault()).format(date);
        } catch (Exception e) {
            return "";
        }
    }

    private static void displayAttachment(Message m, ImageView iv, TextView tvName, String token, String baseUrl) {
        // Check if there's an attachment by looking at name or mime type
        if (m.getAttachmentName() != null || m.getAttachmentMimeType() != null) {
            // Construct the download URL using the message ID
            String url;
            if (baseUrl != null) {
                String cleanBase = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
                url = cleanBase + "/api/v1/chat/messages/" + m.getId() + "/attachment";
            } else {
                url = m.getAttachmentUrl(); // Fallback
            }

            if (url == null) {
                Glide.with(iv.getContext()).clear(iv);
                iv.setVisibility(View.GONE);
                tvName.setVisibility(View.GONE);
                return;
            }

            if (m.getAttachmentMimeType() != null && m.getAttachmentMimeType().startsWith("image/")) {
                iv.setVisibility(View.VISIBLE);
                tvName.setVisibility(View.GONE);

                Object loadTarget = url;
                if (token != null) {
                    loadTarget = new GlideUrl(url, new LazyHeaders.Builder()
                            .addHeader("Authorization", "Bearer " + token)
                            .build());
                }

                // Use a signature to prevent Glide from showing stale cached images for the same URL/ID
                String signatureKey = (m.getTimestamp() != null ? m.getTimestamp() : "") + m.getId();

                Glide.with(iv.getContext()).clear(iv);
                Glide.with(iv.getContext())
                        .load(loadTarget)
                        .signature(new ObjectKey(signatureKey))
                        .diskCacheStrategy(DiskCacheStrategy.ALL)
                        .placeholder(R.drawable.placeholder)
                        .error(R.drawable.placeholder)
                        .into(iv);
            } else {
                Glide.with(iv.getContext()).clear(iv);
                iv.setVisibility(View.GONE);
                tvName.setVisibility(View.VISIBLE);
                tvName.setText(m.getAttachmentName() != null ? m.getAttachmentName() : "Attachment");
            }
        } else {
            Glide.with(iv.getContext()).clear(iv);
            iv.setVisibility(View.GONE);
            tvName.setVisibility(View.GONE);
        }
    }
}