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.example.petstoremobile.R;
import com.example.petstoremobile.databinding.ItemMessageReceivedBinding;
import com.example.petstoremobile.databinding.ItemMessageSentBinding;
import com.example.petstoremobile.models.Message;
import java.util.List;

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 String token;
    private String baseUrl;
    private OnAttachmentClickListener attachmentClickListener;

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

    public void setCurrentUserId(Long id) {
        this.currentUserId = 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);
    }

    @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) {
            // Check for Text
            if (m.getContent() != null && !m.getContent().isEmpty()) {
                binding.tvMessageContent.setVisibility(View.VISIBLE);
                binding.tvMessageContent.setText(m.getContent());
            } else {
                binding.tvMessageContent.setVisibility(View.GONE);
            }
            
            // Check for Attachment
            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) {
            // Check for Text
            if (m.getContent() != null && !m.getContent().isEmpty()) {
                binding.tvMessageContent.setVisibility(View.VISIBLE);
                binding.tvMessageContent.setText(m.getContent());
            } else {
                binding.tvMessageContent.setVisibility(View.GONE);
            }

            // Check for Attachment
            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);
        }
    }

    // helper function to display the attachment to the chat bubble
    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) {
                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());
                }

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