package cc.winboll.studio.positions.adapters;

/**
 * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/09/29 20:25
 * @Describe 位置数据适配器（修复视图复用资源加载，支持滚动后重新绑定数据，Java 7语法适配）
 */


/**
 * Java 7 语法严格适配 + 视图复用资源加载修复：
 * 1. 保留无Lambda/弱引用/线程安全集合等原有适配
 * 2. 修复核心问题：移除 onViewDetachedFromWindow 中关键资源释放，改为 onBind 时重新绑定
 * 3. 强化资源复用：任务视图/距离控件在复用后自动从服务同步最新数据，确保滚动后数据不丢失
 * 4. 优化缓存逻辑：仅清理脱离屏幕且无效的控件缓存，有效控件保留引用供局部更新（如距离）
 */
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.positions.R;
import cc.winboll.studio.positions.models.PositionModel;
import cc.winboll.studio.positions.models.PositionTaskModel;
import cc.winboll.studio.positions.services.MainService;
import cc.winboll.studio.positions.views.PositionTaskListView;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements MainService.TaskUpdateListener {
    public static final String TAG = "PositionAdapter";

    // 视图类型常量（静态常量统一管理）
    private static final int VIEW_TYPE_SIMPLE = 0;
    private static final int VIEW_TYPE_EDIT = 1;

    // 默认配置常量（避免魔法值）
    private static final String DEFAULT_MEMO = "无备注";
    private static final String DEFAULT_TASK_DESC = "新任务";
    private static final int DEFAULT_TASK_DISTANCE = 50; // 单位：米
    private static final String DISTANCE_FORMAT = "实时距离：%.1f 米";
    private static final String DISTANCE_DISABLED = "实时距离：未启用";
    private static final String DISTANCE_ERROR = "实时距离：计算失败";

    // 核心依赖（弱引用+线程安全集合，适配Java 7）
    private final Context mContext;
    private final ArrayList<PositionModel> mCachedPositionList; // 位置缓存（与MainService同步）
    private final WeakReference<MainService> mMainServiceRef;   // 弱引用MainService，防内存泄漏
    // 控件缓存：位置ID → 对应任务列表视图（分别缓存简单/编辑模式，支持复用后快速同步）
    private final ConcurrentHashMap<String, PositionTaskListView> mSimpleTaskViewMap;
    private final ConcurrentHashMap<String, PositionTaskListView> mEditTaskViewMap;
    // 距离控件缓存（用于局部更新距离UI，保留有效引用避免复用后更新失效）
    private final ConcurrentHashMap<String, TextView> mPosDistanceViewMap;

    // 回调接口（仅处理位置逻辑，任务逻辑通过PositionTaskListView+MainService完成）
    public interface OnDeleteClickListener {
        void onDeleteClick(int position);
    }

    public interface OnSavePositionClickListener {
        void onSavePositionClick(int position, PositionModel updatedPos);
    }

    private OnDeleteClickListener mOnDeleteListener;
    private OnSavePositionClickListener mOnSavePosListener;

    // =========================================================================
    // 构造函数（初始化依赖+注册服务监听+初始化控件缓存）
    // =========================================================================
    public PositionAdapter(Context context, ArrayList<PositionModel> cachedPositionList, MainService mainService) {
        this.mContext = context;
        // 容错处理：避免传入null导致空指针
        this.mCachedPositionList = (cachedPositionList != null) ? cachedPositionList : new ArrayList<PositionModel>();
        // 弱引用MainService：防止Adapter持有服务导致内存泄漏（Java 7 弱引用语法）
        this.mMainServiceRef = new WeakReference<MainService>(mainService);
        // 初始化控件缓存（线程安全集合，适配多线程更新场景）
        this.mSimpleTaskViewMap = new ConcurrentHashMap<String, PositionTaskListView>();
        this.mEditTaskViewMap = new ConcurrentHashMap<String, PositionTaskListView>();
        this.mPosDistanceViewMap = new ConcurrentHashMap<String, TextView>();

        // 注册MainService任务监听：服务任务变化时同步刷新任务列表视图
        if (mainService != null) {
            mainService.registerTaskUpdateListener(this);
            LogUtils.d(TAG, "已注册MainService任务监听，确保任务数据与服务同步");
        } else {
            LogUtils.w(TAG, "构造函数：MainService为空，PositionTaskListView无法初始化");
        }

        LogUtils.d(TAG, "Adapter初始化完成：位置数量=" + mCachedPositionList.size());
    }

    // =========================================================================
    // RecyclerView 核心方法（强化视图复用逻辑，复用后自动重新绑定资源）
    // =========================================================================
    @Override
    public int getItemViewType(int position) {
        PositionModel posModel = getPositionByIndex(position);
        return (posModel != null && posModel.isSimpleView()) ? VIEW_TYPE_SIMPLE : VIEW_TYPE_EDIT;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        if (viewType == VIEW_TYPE_SIMPLE) {
            View simpleView = inflater.inflate(R.layout.item_position_simple, parent, false);
            return new SimpleViewHolder(simpleView);
        } else {
            View editView = inflater.inflate(R.layout.item_position_edit, parent, false);
            return new EditViewHolder(editView);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        PositionModel posModel = getPositionByIndex(position);
        if (posModel == null) {
            LogUtils.w(TAG, "onBindViewHolder：位置模型为空（索引=" + position + "），跳过绑定");
            return;
        }
        final String posId = posModel.getPositionId();
        MainService mainService = mMainServiceRef.get();

        // 按视图类型绑定数据（简单模式/编辑模式）—— 核心修复：复用后重新绑定所有资源
        if (holder instanceof SimpleViewHolder) {
            LogUtils.d(TAG, "instanceof SimpleViewHolder（复用/新创建）：位置ID=" + posId);
            SimpleViewHolder simpleHolder = (SimpleViewHolder) holder;
            // 1. 重新绑定位置基础数据（经纬度/备注/距离，确保复用后显示最新数据）
            bindSimplePositionData(simpleHolder, posModel);
            // 2. 重新初始化+绑定简单模式任务视图（复用后从服务同步最新任务，避免数据丢失）
            initAndBindSimpleTaskView(simpleHolder.ptlvSimpleTasks, posId, mainService);
            // 3. 缓存/更新简单模式任务视图+距离控件（覆盖旧缓存，确保引用最新控件）
            mSimpleTaskViewMap.put(posId, simpleHolder.ptlvSimpleTasks);
            mPosDistanceViewMap.put(posId, simpleHolder.tvSimpleDistance);

        } else if (holder instanceof EditViewHolder) {
            LogUtils.d(TAG, "instanceof EditViewHolder（复用/新创建）：位置ID=" + posId);
            EditViewHolder editHolder = (EditViewHolder) holder;
            // 1. 重新绑定位置基础数据（经纬度/备注/距离/距离开关，复用后显示最新状态）
            bindEditPositionData(editHolder, posModel, position);
            // 2. 重新初始化+绑定编辑模式任务视图（复用后同步服务最新任务，支持增删改）
            initAndBindEditTaskView(editHolder.ptlvEditTasks, posId, mainService, editHolder.btnAddTask);
            // 3. 缓存/更新编辑模式任务视图+距离控件（覆盖旧缓存，确保引用最新控件）
            mEditTaskViewMap.put(posId, editHolder.ptlvEditTasks);
            mPosDistanceViewMap.put(posId, editHolder.tvEditDistance);
        }
    }

    @Override
    public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        // 核心修改：仅清理「无效/已回收」的控件缓存，不释放关键资源（支持复用后重新绑定）
        PositionModel posModel = getPositionByIndex(holder.getAdapterPosition());
        if (posModel == null || TextUtils.isEmpty(posModel.getPositionId())) {
            return;
        }
        String posId = posModel.getPositionId();

        // 1. 清理「已脱离视图树/无效」的距离控件缓存（保留有效控件供局部更新）
        if (mPosDistanceViewMap.containsKey(posId)) {
            TextView distanceView = mPosDistanceViewMap.get(posId);
            if (distanceView == null || !distanceView.isAttachedToWindow()) {
                mPosDistanceViewMap.remove(posId);
                LogUtils.d(TAG, "视图脱离屏幕：移除无效距离控件缓存（位置ID=" + posId + "）");
            }
        }

        // 2. 清理「已脱离视图树/无效」的简单模式任务视图缓存（不解绑监听/不清空数据，复用后重新同步）
        if (holder instanceof SimpleViewHolder && mSimpleTaskViewMap.containsKey(posId)) {
            PositionTaskListView taskView = mSimpleTaskViewMap.get(posId);
            if (taskView == null || !taskView.isAttachedToWindow()) {
                mSimpleTaskViewMap.remove(posId);
                LogUtils.d(TAG, "简单模式视图脱离屏幕：移除无效任务视图缓存（位置ID=" + posId + "）");
            }
        }

        // 3. 清理「已脱离视图树/无效」的编辑模式任务视图缓存（同上，保留数据供复用）
        if (holder instanceof EditViewHolder && mEditTaskViewMap.containsKey(posId)) {
            PositionTaskListView taskView = mEditTaskViewMap.get(posId);
            if (taskView == null || !taskView.isAttachedToWindow()) {
                mEditTaskViewMap.remove(posId);
                LogUtils.d(TAG, "编辑模式视图脱离屏幕：移除无效任务视图缓存（位置ID=" + posId + "）");
            }
        }
    }

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

    // =========================================================================
    // 位置数据绑定（保留原有逻辑，确保复用后数据最新）
    // =========================================================================
    /**
     * 绑定简单模式位置数据（仅显示，无编辑操作）—— 复用后重新执行，显示最新数据
     */
    private void bindSimplePositionData(SimpleViewHolder holder, final PositionModel posModel) {
        // 1. 经纬度显示（保留6位小数，格式统一）
        holder.tvSimpleLon.setText(String.format("经度：%.6f", posModel.getLongitude()));
        holder.tvSimpleLat.setText(String.format("纬度：%.6f", posModel.getLatitude()));

        // 2. 备注显示（无备注时显示默认文本）
        String memo = posModel.getMemo();
        holder.tvSimpleMemo.setText("备注：" + (TextUtils.isEmpty(memo) ? DEFAULT_MEMO : memo));

        // 3. 实时距离显示（按状态区分文本+颜色——复用后重新计算显示最新距离）
        updateDistanceDisplay(holder.tvSimpleDistance, posModel);

        // 4. 点击切换到编辑模式
        holder.itemView.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					posModel.setIsSimpleView(false);
					// 精准刷新当前项（避免全量刷新）
					notifyItemChanged(getPositionIndexById(posModel.getPositionId()));
					LogUtils.d(TAG, "简单视图点击：位置ID=" + posModel.getPositionId() + "，切换到编辑视图");
				}
			});
    }

    /**
     * 绑定编辑模式位置数据（支持备注修改/距离开关/删除/保存）—— 复用后重新执行，恢复编辑状态
     */
    private void bindEditPositionData(final EditViewHolder holder, final PositionModel posModel, final int position) {
        final String posId = posModel.getPositionId();

        // 1. 经纬度显示（不可编辑，仅展示）
        holder.tvEditLon.setText(String.format("经度：%.6f", posModel.getLongitude()));
        holder.tvEditLat.setText(String.format("纬度：%.6f", posModel.getLatitude()));

        // 2. 备注编辑（填充现有备注，光标定位到末尾——复用后恢复输入状态）
        String memo = posModel.getMemo();
        if (!TextUtils.isEmpty(memo)) {
            holder.etEditMemo.setText(memo);
            holder.etEditMemo.setSelection(memo.length());
        } else {
            holder.etEditMemo.setText("");
        }

        // 3. 实时距离显示（与简单模式逻辑一致——复用后显示最新距离）
        updateDistanceDisplay(holder.tvEditDistance, posModel);

        // 4. 距离开关状态（匹配位置模型中的启用状态——复用后恢复开关状态）
        holder.rgDistanceSwitch.check(posModel.isEnableRealPositionDistance()
									  ? R.id.rb_distance_enable
									  : R.id.rb_distance_disable);

        // 5. 取消编辑：切换回简单模式+隐藏软键盘
        holder.btnCancel.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					posModel.setIsSimpleView(true);
					notifyItemChanged(position);
					hideSoftKeyboard(v);
					LogUtils.d(TAG, "取消编辑：位置ID=" + posId + "，切换回简单视图");
				}
			});

        // 6. 删除位置：回调Activity处理（Adapter不直接操作数据）
        holder.btnDelete.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					if (mOnDeleteListener != null) {
						mOnDeleteListener.onDeleteClick(position);
					}
					hideSoftKeyboard(v);
					LogUtils.d(TAG, "触发删除：通知Activity处理位置ID=" + posId + "的删除逻辑");
				}
			});

        // 7. 保存位置：收集参数→更新模型→回调Activity→切换视图
        holder.btnSave.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					// 收集编辑后的数据
					String newMemo = holder.etEditMemo.getText().toString().trim();
					boolean isDistanceEnable = (holder.rgDistanceSwitch.getCheckedRadioButtonId() == R.id.rb_distance_enable);

					// 构建更新后的位置模型（保留核心不可编辑字段）
					PositionModel updatedPos = new PositionModel();
					updatedPos.setPositionId(posId);
					updatedPos.setLongitude(posModel.getLongitude());
					updatedPos.setLatitude(posModel.getLatitude());
					updatedPos.setMemo(newMemo);
					updatedPos.setIsEnableRealPositionDistance(isDistanceEnable);
					updatedPos.setIsSimpleView(true);

					// 回调Activity保存（由Activity同步MainService）
					if (mOnSavePosListener != null) {
						mOnSavePosListener.onSavePositionClick(position, updatedPos);
					}

					// 本地同步状态（避免刷新延迟）
					posModel.setMemo(newMemo);
					posModel.setIsEnableRealPositionDistance(isDistanceEnable);
					posModel.setIsSimpleView(true);
					notifyItemChanged(position);
					hideSoftKeyboard(v);
					LogUtils.d(TAG, "保存位置：ID=" + posId + "，新备注=" + newMemo + "，距离启用=" + isDistanceEnable);
				}
			});
    }

    // =========================================================================
    // PositionTaskListView 集成（强化复用逻辑：复用后重新同步服务数据，确保数据不丢失）
    // =========================================================================
    /**
     * 初始化+绑定简单模式任务列表视图——复用后重新执行，从服务同步最新任务
     */
    private void initAndBindSimpleTaskView(PositionTaskListView taskView, final String posId, MainService mainService) {
        if (taskView == null || TextUtils.isEmpty(posId) || mainService == null) {
            LogUtils.w(TAG, "初始化简单模式任务视图失败：参数无效（posId=" + posId + "，service=" + mainService + "）");
            return;
        }

        // 1. 初始化任务视图（绑定MainService+当前位置ID——复用后重新绑定，确保服务引用有效）
        taskView.init(mainService, posId);
        // 2. 设置为简单模式（仅展示，隐藏编辑按钮——复用后恢复视图模式）
        taskView.setViewStatus(PositionTaskListView.VIEW_MODE_SIMPLE);
		// 3. 关键：复用后强制从服务同步最新任务（避免显示旧数据，核心修复点）
		taskView.syncTasksFromMainService();

		// 4. 任务更新回调（服务任务变化时重新同步——复用后重新绑定回调，避免监听失效）
		taskView.setOnTaskUpdatedListener(new PositionTaskListView.OnTaskUpdatedListener() {
				@Override
				public void onTaskUpdated(String positionId, ArrayList updatedTasks) {
					LogUtils.d(TAG, "简单模式任务更新：位置ID=" + positionId + "，已启用任务数=" + updatedTasks.size());
				}
			});

		LogUtils.d(TAG, "初始化/复用简单模式任务视图完成：位置ID=" + posId);
	}

	/**
	 - 初始化+绑定编辑模式任务列表视图——复用后重新执行，从服务同步最新任务+恢复编辑功能
	 */
	private void initAndBindEditTaskView(final PositionTaskListView taskView, final String posId,
										 MainService mainService, Button btnAddTask) {
		if (taskView == null || TextUtils.isEmpty(posId) || mainService == null || btnAddTask == null) {
			LogUtils.w(TAG, "初始化编辑模式任务视图失败：参数无效（posId=" + posId + "，btnAddTask=" + btnAddTask + "）");
			return;
		}
		// 1. 初始化任务视图（绑定MainService+当前位置ID——复用后重新绑定，确保服务引用有效）
		taskView.init(mainService, posId);
		// 2. 设置为编辑模式（显示编辑/删除按钮——复用后恢复视图模式）
		taskView.setViewStatus(PositionTaskListView.VIEW_MODE_EDIT);
		// 3. 关键：复用后强制从服务同步最新任务（避免显示旧数据，核心修复点）
		taskView.syncTasksFromMainService();// 4. 绑定“新增任务”按钮逻辑（复用后重新绑定点击事件，避免按钮点击失效）
		btnAddTask.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					// 构建默认任务模型（关联当前位置ID，使用默认配置）
					PositionTaskModel newTask = new PositionTaskModel();
					newTask.setTaskId(PositionTaskModel.genTaskId()); // 生成唯一任务ID（需模型类实现）
					newTask.setPositionId(posId);                     // 绑定当前位置
					newTask.setTaskDescription(DEFAULT_TASK_DESC);    // 默认描述
					newTask.setDiscussDistance(DEFAULT_TASK_DISTANCE); // 默认触发距离（50米）
					newTask.setIsEnable(true);                        // 默认启用
					newTask.setIsBingo(false);                        // 初始未触发// 调用任务视图的新增方法（假设视图已实现addNewTask，内部同步MainService）
					taskView.addNewTask(newTask);
					hideSoftKeyboard(v); // 隐藏软键盘，提升体验
					LogUtils.d(TAG, "编辑模式新增任务：位置ID=" + posId + "，任务ID=" + newTask.getTaskId());
				}
			});// 5. 任务更新回调（通知外部任务变化——复用后重新绑定回调，确保交互正常）
		taskView.setOnTaskUpdatedListener(new PositionTaskListView.OnTaskUpdatedListener() {
				@Override
				public void onTaskUpdated(String positionId, ArrayList updatedTasks) {
					LogUtils.d(TAG, "编辑模式任务更新：位置ID=" + positionId + "，当前任务数=" + updatedTasks.size());
				}
			});
			LogUtils.d(TAG, "初始化/复用编辑模式任务视图完成：位置ID=" + posId);
	}

	// =========================================================================
	// 工具方法（保留原有逻辑，适配资源复用场景）
	// =========================================================================
	/**

	 - 更新距离显示（复用后重新执行，确保显示最新距离+颜色——适配资源复用）
	 */
	private void updateDistanceDisplay(TextView distanceView, PositionModel posModel) {
		if (distanceView == null || posModel == null) {
			LogUtils.w(TAG, "更新距离显示失败：参数为空（控件/位置模型）");
			return;
		}// 场景1：距离未启用（灰色文本）
		if (!posModel.isEnableRealPositionDistance()) {
			distanceView.setText(DISTANCE_DISABLED);
			distanceView.setTextColor(mContext.getResources().getColor(R.color.gray));
			return;
		}// 场景2：距离计算失败（红色文本，用-1标记失败状态）
		double distance = posModel.getRealPositionDistance();
		if (distance < 0) {
			distanceView.setText(DISTANCE_ERROR);
			distanceView.setTextColor(mContext.getResources().getColor(R.color.red));
			return;
		}// 场景3：正常显示距离（按距离范围设置颜色——复用后重新计算颜色）
		distanceView.setText(String.format(DISTANCE_FORMAT, distance));
		if (distance <= 100) {
			distanceView.setTextColor(mContext.getResources().getColor(R.color.green)); // 近距离（≤100米）
		} else if (distance <= 500) {
			distanceView.setTextColor(mContext.getResources().getColor(R.color.yellow));// 中距离（≤500米）
		} else {
			distanceView.setTextColor(mContext.getResources().getColor(R.color.red));   // 远距离（>500米）
		}
	}

	/**

	 - 根据索引获取位置模型（容错处理，避免越界/空指针——适配复用后索引变化场景）
	 */
	private PositionModel getPositionByIndex(int index) {
		if (mCachedPositionList == null || index < 0 || index >= mCachedPositionList.size()) {
			LogUtils.w(TAG, "获取位置模型失败：无效索引（" + index + "）或缓存为空");
			return null;
		}
		return mCachedPositionList.get(index);
	}

	/**

	 - 根据位置ID获取列表索引（用于精准刷新视图——适配复用后视图位置变化）
	 */
	private int getPositionIndexById(String positionId) {
		if (TextUtils.isEmpty(positionId) || mCachedPositionList == null || mCachedPositionList.isEmpty()) {
			LogUtils.w(TAG, "获取位置索引失败：参数无效（ID/缓存为空）");
			return -1;
		}// Java 7 增强for循环遍历（替代Lambda，适配语法）
		for (int i = 0; i < mCachedPositionList.size(); i++) {
			PositionModel pos = mCachedPositionList.get(i);
			if (positionId.equals(pos.getPositionId())) {
				return i;
			}
		}
		LogUtils.w(TAG, "获取位置索引失败：未找到ID=" + positionId);
		return -1;
	}

	/**

	 - 局部更新距离UI（仅更新指定位置的距离，避免全量刷新卡顿——适配复用后控件缓存有效场景）
	 */
	public void updateSinglePositionDistance(String positionId) {
		if (TextUtils.isEmpty(positionId) || mPosDistanceViewMap.isEmpty()) {
			LogUtils.w(TAG, "局部更新距离失败：ID无效或无控件缓存（ID=" + positionId + "）");
			return;
		}
		// 1. 获取服务端最新位置数据（带重试，避免服务临时回收）
		MainService mainService = getMainServiceWithRetry(2);
		if (mainService == null) {
			LogUtils.e(TAG, "局部更新距离失败：无法获取MainService");
			return;
		}
		PositionModel latestPos = null;
		try {
			ArrayList servicePosList = mainService.getPositionList();
			if (servicePosList != null && !servicePosList.isEmpty()) {
				// Java 7 迭代器遍历，避免ConcurrentModificationException
				Iterator iter = servicePosList.iterator();
				while (iter.hasNext()) {
					PositionModel pos = (PositionModel)iter.next();
					if (positionId.equals(pos.getPositionId())) {
						latestPos = pos;
						break;
					}
				}
			}
		} catch (Exception e) {
			LogUtils.d(TAG, "获取最新位置数据失败（ID=" + positionId + "）" + e);
			return;
		}if (latestPos == null) {
			LogUtils.w(TAG, "局部更新距离失败：未找到位置ID=" + positionId);
			return;
		}
		// 2. 更新距离控件（确保主线程操作，避免跨线程异常——适配复用后控件已重新绑定）
		final TextView distanceView = mPosDistanceViewMap.get(positionId);
		if (distanceView != null && distanceView.isAttachedToWindow()) {
			final PositionModel finalLatestPos = latestPos;
			distanceView.post(new Runnable() {
					@Override
					public void run() {
						updateDistanceDisplay(distanceView, finalLatestPos);
					}
				});
			LogUtils.d(TAG, "局部更新距离完成：位置ID=" + positionId + "，距离=" + latestPos.getRealPositionDistance() + "米");
		} else {
			mPosDistanceViewMap.remove(positionId); // 移除无效控件缓存（如视图已被销毁）
			LogUtils.w(TAG, "局部更新距离失败：控件已回收/脱离视图树（ID=" + positionId + "）");
		}
	}

	/**
	 - 全量更新位置数据（从服务同步最新数据，过滤无效/重复项——适配复用后全量刷新场景）
	 */
	public void updateAllPositionData(ArrayList<PositionModel> newPosList) {
		if (newPosList == null) {
			LogUtils.w(TAG, "全量更新位置数据失败：新列表为空");
			return;
		}
		// 1. 过滤无效位置（校验核心字段：ID/经纬度合法）
		ArrayList<PositionModel> validPosList = new ArrayList<PositionModel>();
		for (PositionModel pos : newPosList) {
			if (TextUtils.isEmpty(pos.getPositionId())
				|| pos.getLongitude() < -180 || pos.getLongitude() > 180
				|| pos.getLatitude() < -90 || pos.getLatitude() > 90) {
				LogUtils.w(TAG, "过滤无效位置：ID=" + pos.getPositionId() + "（经纬度/ID非法）");
				continue;
			}
			validPosList.add(pos);
		}
		// 2. 去重（按位置ID去重，保留服务端最新数据）
		ConcurrentHashMap<String, PositionModel> uniquePosMap = new ConcurrentHashMap<String, PositionModel>();
		for (PositionModel pos : validPosList) {
			uniquePosMap.put(pos.getPositionId(), pos); // 相同ID覆盖，保留最新
		}
		ArrayList uniquePosList = new ArrayList(uniquePosMap.values());// 3. 同步到本地缓存+刷新UI（刷新后触发onBind，自动重新绑定资源）
		this.mCachedPositionList.clear();
		this.mCachedPositionList.addAll(uniquePosList);
		// 清空旧控件缓存（避免引用失效数据，刷新后重新缓存新控件）
		mPosDistanceViewMap.clear();
		mSimpleTaskViewMap.clear();
		mEditTaskViewMap.clear();
		notifyDataSetChanged();
		LogUtils.d(TAG, "全量更新位置数据完成：原数量=" + newPosList.size() + "，过滤后=" + uniquePosList.size());
	}

	/**
	 - 隐藏软键盘（编辑完成后调用，提升用户体验——适配复用后软键盘残留问题）
	 */
	private void hideSoftKeyboard(View view) {
		if (mContext == null || view == null) {
			LogUtils.w(TAG, "隐藏软键盘失败：参数为空（上下文/视图）");
			return;
		}InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
		if (imm != null) {
			imm.hideSoftInputFromWindow(view.getWindowToken(), 0); // 强制隐藏
		}
	}

	/**
	 - 带重试的服务获取（解决弱引用临时回收问题，最多重试2次——适配复用后服务引用失效场景）
	 */
	private MainService getMainServiceWithRetry(int retryCount) {
		MainService mainService = mMainServiceRef.get();
		if (mainService != null) {
			return mainService;
		}
		// 重试逻辑：每次间隔100ms，避免频繁重试
		for (int i = 0; i < retryCount; i++) {
			try {
				Thread.sleep(100);
				mainService = mMainServiceRef.get();
				if (mainService != null) {
					LogUtils.d(TAG, "重试获取MainService成功（第" + (i + 1) + "次）");
					return mainService;
				}
			} catch (InterruptedException e) {
				LogUtils.d(TAG, "重试获取服务时线程被中断" + e);
				Thread.currentThread().interrupt(); // 恢复中断状态
				break;
			}
		}LogUtils.e(TAG, "重试" + retryCount + "次后仍未获取到MainService");
		return null;
	}

	// =========================================================================
	// 实现 MainService.TaskUpdateListener 接口（服务任务变化时回调——适配复用后任务同步）
	// =========================================================================
	@Override
	public void onTaskUpdated() {
		LogUtils.d(TAG, "收到MainService任务更新通知，同步所有任务列表视图（含复用视图）");

		// 1. 同步简单模式任务视图（仅显示已启用任务——适配复用后视图已重新缓存）
		if (!mSimpleTaskViewMap.isEmpty()) {
			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mSimpleTaskViewMap.entrySet().iterator();
			while (iter.hasNext()) {
				ConcurrentHashMap.Entry<String, PositionTaskListView> entry = iter.next();
				PositionTaskListView taskView = entry.getValue();
				if (taskView != null && taskView.isAttachedToWindow()) {
					taskView.syncTasksFromMainService(); // 从服务同步最新任务（复用后也能更新）
				} else {
					iter.remove(); // 移除无效视图缓存（如视图已脱离屏幕且未复用）
				}
			}
		}

		// 2. 同步编辑模式任务视图（支持编辑的全量任务——适配复用后视图已重新缓存）
		if (!mEditTaskViewMap.isEmpty()) {
			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mEditTaskViewMap.entrySet().iterator();
			while (iter.hasNext()) {
				ConcurrentHashMap.Entry<String, PositionTaskListView> entry = iter.next();
				PositionTaskListView taskView = entry.getValue();
				if (taskView != null && taskView.isAttachedToWindow()) {
					taskView.syncTasksFromMainService(); // 从服务同步最新任务（复用后也能更新）
				} else {
					iter.remove(); // 移除无效视图缓存
				}
			}
		}
	}

	// =========================================================================
	// 回调设置方法（供Activity绑定交互逻辑——适配复用后回调不失效）
	// =========================================================================
	public void setOnDeleteClickListener(OnDeleteClickListener listener) {
		this.mOnDeleteListener = listener;
	}

	public void setOnSavePositionClickListener(OnSavePositionClickListener listener) {
		this.mOnSavePosListener = listener;
	}

	// =========================================================================
	// 资源释放（Activity销毁时调用，彻底释放引用，避免内存泄漏——保留原有安全逻辑）
	// =========================================================================
	public void release() {
		// 1. 反注册MainService任务监听（解除服务绑定）
		MainService mainService = mMainServiceRef.get();
		if (mainService != null) {
			mainService.unregisterTaskUpdateListener(this);
			LogUtils.d(TAG, "已反注册MainService任务监听");
		}

		// 2. 释放简单模式任务视图资源（清空数据+解绑监听——仅在Activity销毁时执行，不复用场景）
		if (!mSimpleTaskViewMap.isEmpty()) {
			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mSimpleTaskViewMap.entrySet().iterator();
			while (iter.hasNext()) {
				PositionTaskListView taskView = iter.next().getValue();
				if (taskView != null) {
					taskView.clearData();
					taskView.setOnTaskUpdatedListener(null);
				}
				iter.remove();
			}
		}

		// 3. 释放编辑模式任务视图资源（清空数据+解绑监听——仅在Activity销毁时执行）
		if (!mEditTaskViewMap.isEmpty()) {
			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mEditTaskViewMap.entrySet().iterator();
			while (iter.hasNext()) {
				PositionTaskListView taskView = iter.next().getValue();
				if (taskView != null) {
					taskView.clearData();
					taskView.setOnTaskUpdatedListener(null);
				}
				iter.remove();
			}
		}

		// 4. 清空其他缓存+置空引用（彻底释放，避免内存泄漏）
		mPosDistanceViewMap.clear();
		if (mCachedPositionList != null) {
			mCachedPositionList.clear();
		}
		mOnDeleteListener = null;
		mOnSavePosListener = null;

		LogUtils.d(TAG, "Adapter资源已完全释放（任务视图资源释放+缓存清空+引用置空）");
	}

	// =========================================================================
	// 静态内部类：ViewHolder（与布局严格对应，避免外部引用导致内存泄漏）
	// =========================================================================
	/**
	 - 简单模式ViewHolder（对应 item_position_simple.xml，含简单模式任务列表视图）
	 */
	public static class SimpleViewHolder extends RecyclerView.ViewHolder {
		TextView tvSimpleLon;         // 经度显示
		TextView tvSimpleLat;         // 纬度显示
		TextView tvSimpleMemo;        // 备注显示
		TextView tvSimpleDistance;    // 距离显示
		PositionTaskListView ptlvSimpleTasks; // 简单模式任务列表视图
		public SimpleViewHolder(View itemView) {
			super(itemView);
			// 绑定布局控件（与XML中ID严格一致，避免运行时空指针）
			tvSimpleLon = (TextView) itemView.findViewById(R.id.tv_simple_longitude);
			tvSimpleLat = (TextView) itemView.findViewById(R.id.tv_simple_latitude);
			tvSimpleMemo = (TextView) itemView.findViewById(R.id.tv_simple_memo);
			tvSimpleDistance = (TextView) itemView.findViewById(R.id.tv_simple_distance);
			ptlvSimpleTasks = (PositionTaskListView) itemView.findViewById(R.id.ptlv_simple_tasks);
		}
	}

	/**
	 - 编辑模式ViewHolder（对应 item_position_edit.xml，含编辑模式任务列表视图）
	 */
	public static class EditViewHolder extends RecyclerView.ViewHolder {
		TextView tvEditLon;           // 经度显示（不可编辑）
		TextView tvEditLat;           // 纬度显示（不可编辑）
		EditText etEditMemo;          // 备注编辑
		TextView tvEditDistance;      // 距离显示
		RadioGroup rgDistanceSwitch;  // 距离启用/禁用开关
		Button btnCancel;             // 取消编辑按钮
		Button btnDelete;             // 删除位置按钮
		Button btnSave;               // 保存位置按钮
		Button btnAddTask;            // 新增任务按钮
		TextView tvTaskCount;         // 任务数量显示（兼容旧布局，可隐藏）
		PositionTaskListView ptlvEditTasks; // 编辑模式任务列表视图
		public EditViewHolder(View itemView) {
			super(itemView);
			// 绑定布局控件（与XML中ID严格一致，避免运行时空指针）
			tvEditLon = (TextView) itemView.findViewById(R.id.tv_edit_longitude);
			tvEditLat = (TextView) itemView.findViewById(R.id.tv_edit_latitude);
			etEditMemo = (EditText) itemView.findViewById(R.id.et_edit_memo);
			tvEditDistance = (TextView) itemView.findViewById(R.id.tv_edit_distance);
			rgDistanceSwitch = (RadioGroup) itemView.findViewById(R.id.rg_distance_switch);
			btnCancel = (Button) itemView.findViewById(R.id.btn_edit_cancel);
			btnDelete = (Button) itemView.findViewById(R.id.btn_edit_delete);
			btnSave = (Button) itemView.findViewById(R.id.btn_edit_save);
			btnAddTask = (Button) itemView.findViewById(R.id.btn_add_task);
			tvTaskCount = (TextView) itemView.findViewById(R.id.tv_task_count);
			ptlvEditTasks = (PositionTaskListView) itemView.findViewById(R.id.ptlv_edit_tasks);
		}
	}

	// =========================================================================
	// 补充：PositionTaskListView 必要方法适配（确保视图类已实现以下基础方法）
	// （若视图类未实现，需在 PositionTaskListView 中添加对应逻辑，否则复用后功能异常）
	// =========================================================================
	public static class PositionTaskListViewRequiredMethods {
		/**
		 1. - init 方法：初始化任务视图（绑定服务+位置ID——复用后重新绑定，确保服务引用有效）
		 - 需在 PositionTaskListView 中添加：
		 - public void init(MainService mainService, String positionId) {
		 - this.mMainServiceRef = new WeakReference(mainService); // 弱引用服务，防泄漏
		 - this.mPositionId = positionId; // 绑定当前位置ID（复用后更新为当前位置ID）
		 - }
		 */

		/**
		 2. - setViewStatus 方法：设置视图模式（简单/编辑——复用后恢复对应模式UI）
		 - 需在 PositionTaskListView 中添加：
		 - public static final int VIEW_MODE_SIMPLE = 0; // 仅显示（隐藏编辑/删除按钮）
		 - public static final int VIEW_MODE_EDIT = 1;   // 可编辑（显示编辑/删除按钮）
		 - private int mViewMode;
		 - public void setViewStatus(int viewMode) {
		 - this.mViewMode = viewMode;
		 - // 根据模式控制按钮显示：简单模式隐藏编辑按钮，编辑模式显示
		 - if (mEditBtn != null) mEditBtn.setVisibility(viewMode == VIEW_MODE_EDIT ? View.VISIBLE : View.GONE);
		 - if (mDeleteBtn != null) mDeleteBtn.setVisibility(viewMode == VIEW_MODE_EDIT ? View.VISIBLE : View.GONE);
		 - }
		 */

		/**
		 3. - syncTasksFromMainService 方法：从服务同步任务数据（复用后核心方法，避免旧数据）
		 - 需在 PositionTaskListView 中添加：
		 - public void syncTasksFromMainService() {
		 - MainService mainService = mMainServiceRef.get();
		 - if (mainService == null || TextUtils.isEmpty(mPositionId)) return;
		 - // 根据视图模式拉取对应任务：简单模式仅拉已启用，编辑模式拉全部
		 - ArrayList tasks = (mViewMode == VIEW_MODE_SIMPLE)
		 - ? mainService.getEnabledTasksByPositionId(mPositionId)
		 - : mainService.getTasksByPositionId(mPositionId);
		 - // 更新列表数据（刷新UI，确保复用后显示最新任务）
		 - if (mTaskAdapter != null) {
		 - mTaskAdapter.setTaskList(tasks);
		 - mTaskAdapter.notifyDataSetChanged();
		 - }
		 - // 通知外部任务更新（如Adapter需要联动）
		 - if (mTaskUpdateListener != null) mTaskUpdateListener.onTaskUpdated(mPositionId, tasks);
		 - }
		 */

		/**
		 4. - addNewTask 方法：新增任务（同步服务+刷新列表——复用后功能正常）
		 - 需在 PositionTaskListView 中添加：
		 - public void addNewTask(PositionTaskModel newTask) {
		 - if (newTask == null || TextUtils.isEmpty(newTask.getPositionId())) return;
		 - MainService mainService = mMainServiceRef.get();
		 - if (mainService != null) {
		 - mainService.addTask(newTask); // 同步到服务（确保数据持久化）
		 - syncTasksFromMainService();   // 新增后立即同步，刷新列表
		 - Toast.makeText(getContext(), "任务新增成功", Toast.LENGTH_SHORT).show();
		 - } else {
		 - Toast.makeText(getContext(), "服务未就绪，新增失败", Toast.LENGTH_SHORT).show();
		 - }
		 - }
		 */

		/**
		 5. - clearData 方法：清空任务数据（仅在Activity销毁时调用，不复用场景）
		 - 需在 PositionTaskListView 中添加：
		 - public void clearData() {
		 - if (mTaskList != null) mTaskList.clear(); // 清空本地任务列表
		 - if (mTaskAdapter != null) mTaskAdapter.notifyDataSetChanged(); // 刷新空UI
		 - }
		 */

		/**
		 6. - setOnTaskUpdatedListener 方法：设置任务更新回调（复用后重新绑定，避免回调失效）
		 - 需在 PositionTaskListView 中添加：
		 - public interface OnTaskUpdatedListener {
		 - void onTaskUpdated(String positionId, ArrayList updatedTasks);
		 - }
		 - private OnTaskUpdatedListener mTaskUpdateListener;
		 - public void setOnTaskUpdatedListener(OnTaskUpdatedListener listener) {
		 - this.mTaskUpdateListener = listener;
		 - }
		 */
	}
}
