package com.ardrawing.ardrawingspace.adapter;

import android.content.Context;
import android.content.Intent;
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.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;

import com.ardrawing.ardrawingspace.R;
import com.ardrawing.ardrawingspace.activity.CategoryActivity;
import com.ardrawing.ardrawingspace.activity.DrawingActivity;
import com.ardrawing.ardrawingspace.room.AppDatabase;
import com.ardrawing.ardrawingspace.room.SpaceEntity;
import com.ardrawing.ardrawingspace.util.AppExecutors;
import com.ardrawing.ardrawingspace.util.DeleteCallback;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;

import java.util.ArrayList;
import java.util.List;

public class SpaceRecyclerViewAdapter extends RecyclerView.Adapter<SpaceRecyclerViewAdapter.ItemViewHolder> {
    private static final int DISPLAY_MODE_CATEGORY = 0;
    private static final int DISPLAY_MODE_DRAWING = 1;
    private static final int CORNER_RADIUS = 32;
    private static final int PLACEHOLDER_RES = R.mipmap.placeholder;
    private static final int LIKE_ICON = R.drawable.like;
    private static final int UNLIKE_ICON = R.drawable.un_like;

    private List<SpaceEntity> spaceEntityList;
    private final Context context;
    private final int displayMode;
    private DeleteCallback deleteCallback;

    public SpaceRecyclerViewAdapter(Context context, List<SpaceEntity> spaceEntityList, int displayMode) {
        this.context = context;
        this.spaceEntityList = new ArrayList<>(spaceEntityList);
        this.displayMode = displayMode;
    }

    public void updateItems(List<SpaceEntity> newItems) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new SpaceDiffCallback(this.spaceEntityList, newItems));
        this.spaceEntityList = new ArrayList<>(newItems);
        diffResult.dispatchUpdatesTo(this);
    }

    public void setDeleteCallback(DeleteCallback deleteCallback) {
        this.deleteCallback = deleteCallback;
    }

    @NonNull
    @Override
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View itemView = inflater.inflate(R.layout.item_space, parent, false);
        return new ItemViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
        SpaceEntity currentItem = spaceEntityList.get(position);
        String displayName = getTitle(currentItem);
        holder.renderItem(currentItem, displayName, displayMode);
    }

    private String getTitle(SpaceEntity item) {
        if (displayMode == DISPLAY_MODE_CATEGORY) {
            String path = item.getImagePath();
            String[] segments = path.split("/");
            return segments.length > 0 ? segments[0].split("_")[1] : "";
        }
        return "";
    }

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

    public class ItemViewHolder extends RecyclerView.ViewHolder {
        private final ImageView previewImage;
        private final ImageView likeIcon;
        private final ImageView deleteIcon;
        private final TextView titleText;

        public ItemViewHolder(@NonNull View view) {
            super(view);
            previewImage = view.findViewById(R.id.item_image);
            likeIcon = view.findViewById(R.id.like);
            deleteIcon = view.findViewById(R.id.delete);
            titleText = view.findViewById(R.id.title);
        }

        void renderItem(SpaceEntity item, String displayName, int mode) {
            if (mode == DISPLAY_MODE_CATEGORY) {
                titleText.setText(displayName);
                titleText.setVisibility(View.VISIBLE);
                likeIcon.setVisibility(View.GONE);
                deleteIcon.setVisibility(View.GONE);
            } else if (mode == DISPLAY_MODE_DRAWING) {
                titleText.setVisibility(View.GONE);
                likeIcon.setVisibility(View.VISIBLE);
                deleteIcon.setVisibility(View.VISIBLE);
            }

            loadImageContent(item.getImagePath());
            updateFavoriteIcon(item);
            attachListeners(item, mode);
        }

        private void loadImageContent(String path) {
            String formattedPath = adjustImagePath(path);
            Glide.with(context)
                    .load(formattedPath)
                    .placeholder(PLACEHOLDER_RES)
                    .apply(new RequestOptions()
                            .transform(new CenterCrop(), new RoundedCorners(CORNER_RADIUS)))
                    .into(previewImage);
        }

        private String adjustImagePath(String path) {
            return path.startsWith("/data/user/") ? path : "file:///android_asset/" + path;
        }

        private void updateFavoriteIcon(SpaceEntity item) {
            int iconRes = item.isFavorite() ? LIKE_ICON : UNLIKE_ICON;
            likeIcon.setImageResource(iconRes);
        }

        private void attachListeners(SpaceEntity item, int mode) {
            previewImage.setOnClickListener(v -> handleImageTap(item, mode));
            likeIcon.setOnClickListener(v -> toggleFavorite(item));
            deleteIcon.setOnClickListener(v -> onDeleteClicked(item));
        }

        private void onDeleteClicked(SpaceEntity item) {
            int position = getAdapterPosition();
            if (position != RecyclerView.NO_POSITION && deleteCallback != null) {
                deleteCallback.onDelete(item);
            }
        }

        private void handleImageTap(SpaceEntity item, int mode) {
            Intent intent = createIntent(item, mode);
            context.startActivity(intent);
        }

        private Intent createIntent(SpaceEntity item, int mode) {
            Class<?> targetActivity = mode == DISPLAY_MODE_CATEGORY ? CategoryActivity.class : DrawingActivity.class;
            return new Intent(context, targetActivity)
                    .putExtra("imagePath", item.getImagePath());
        }

        private void toggleFavorite(SpaceEntity item) {
            item.setFavorite(!item.isFavorite());
            persistItemUpdate(item);
            notifyItemChanged(getAdapterPosition());
        }

        private void persistItemUpdate(SpaceEntity item) {
            AppExecutors.getInstance().diskIO().execute(() -> {
                AppDatabase db = AppDatabase.getInstance(context);
                db.dao().update(item);
            });
        }
    }

    private static class SpaceDiffCallback extends DiffUtil.Callback {
        private final List<SpaceEntity> oldList;
        private final List<SpaceEntity> newList;

        public SpaceDiffCallback(List<SpaceEntity> oldList, List<SpaceEntity> newList) {
            this.oldList = oldList != null ? new ArrayList<>(oldList) : new ArrayList<>();
            this.newList = newList != null ? new ArrayList<>(newList) : new ArrayList<>();
        }

        @Override
        public int getOldListSize() {
            return oldList.size();
        }

        @Override
        public int getNewListSize() {
            return newList.size();
        }

        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            return oldList.get(oldItemPosition).getId() == newList.get(newItemPosition).getId();
        }

        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            return oldList.get(oldItemPosition).equals(newList.get(newItemPosition));
        }
    }
}