<template>
	<view class="patient-group-page">
	
		<!-- 头部 -->
		 <view class="navbox">
			<view class="status_bar"></view>
			<uni-nav-bar
			left-icon="left" 
			title="患者分组" 
			@clickLeft="goBack"
			color="#8B2316"
			:border="false"
			backgroundColor="#eeeeee"
		>
			<template #right>
				<view class="save-text" @click="confirmGroup">确定({{ totalSelectedCount }})</view>
			</template>
		</uni-nav-bar>
		 </view>
		<!-- 筛选排序栏 -->
		<!-- <view class="filter-sort-bar">
			<view class="sort-section" @click="toggleGroupSort">
				<text class="sort-label">{{ groupSortTitle }}</text>
				<view class="imgbox">
					<up-image  :src="upImg" width="26rpx" height="26rpx" ></up-image>
				</view>
			</view>
			<view class="divider"></view>
			<view class="current-sort" @click="toggleInnerSort">
				<text class="sort-text">{{ innerSortTitle }}</text>
				<view class="imgbox">
					<up-image  :src="upImg" width="26rpx" height="26rpx" ></up-image>
				</view>
			</view>
		</view> -->

		<!-- 分组排序弹窗 -->
		<view v-if="showGroupSort" class="popup-panel">
			<view class="popup-item" :class="{ active: group_sort==0 }" @click.stop="chooseGroupSort('letter')">
				<text class="item-text">按首字母</text>
				<uni-icons v-if="selectedGroupSort==='letter'" type="checkmarkempty" color="#8B2316" size="22"></uni-icons>
			</view>
			<view class="popup-divider"></view>
			<view class="popup-item" :class="{ active:group_sort==1}" @click.stop="chooseGroupSort('count')">
				<text class="item-text">分组人数</text>
				<uni-icons v-if="selectedGroupSort==='count'" type="checkmarkempty" color="#8B2316" size="22"></uni-icons>
			</view>
		</view>
		<view v-if="showGroupSort" class="popup-mask" @click="closeGroupSort"></view>

		<!-- 组内排序弹窗 -->
		<view v-if="showInnerSort" class="popup-panel">
			<view class="popup-item" :class="{ active:list_sort==0 }" @click.stop="chooseInnerSort('letter')">
				<text class="item-text">按首字母</text>
				<uni-icons v-if="selectedInnerSort==='letter'" type="checkmarkempty" color="#8B2316" size="22"></uni-icons>
			</view>
			<view class="popup-divider"></view>
			<view class="popup-item" :class="{ active:list_sort==1 }" @click.stop="chooseInnerSort('count')">
				<text class="item-text">随访时间</text>
				<uni-icons v-if="selectedInnerSort==='count'" type="checkmarkempty" color="#8B2316" size="22"></uni-icons>
			</view>
		</view>
		<view v-if="showInnerSort" class="popup-mask" @click="closeInnerSort"></view>

		<!-- 患者列表 -->
		<scroll-view class="patient-list-section" scroll-y="true" :style="{ height: scrollViewHeight }">
			<!-- 分组循环渲染 -->
			<view class="groupcell" v-for="(group, gi) in groups" :key="group.uuid || gi">
				<view class="section-title" @click="toggleGroup(gi)">
					<view class="left">
						<view class="imgbox" :class="{ 'active':openGroups[gi] }">
							<up-image v-if="!openGroups[gi]" :src="groupRightImg" width="19rpx" height="32rpx" ></up-image>
							<up-image v-else :src="groupDownImg" width="32rpx" height="19rpx" ></up-image>
						</view>
						<view class="title">{{ group.name || '未命名分组' }} | {{ group.patientNum || (group.patientList ? group.patientList.length : 0) }}</view>
					</view>
					<view class="right-checkbox" @click.stop="toggleGroupSelection(gi)" v-if="group.patientList.length > 0">
						<view class="checkbox" :class="{ 'checked': isGroupSelected(gi) }">
							<uni-icons v-if="isGroupSelected(gi)" type="checkmarkempty" color="#8B2316" size="16"></uni-icons>
						</view>
					</view>
				</view>
				<view class="patient-list" v-if="openGroups[gi]">
					<view class="patient-item" v-for="(patient, index) in (group.patientList || [])" :key="patient.uuid || index">
						
						<view class="namebox">
							<view class="patient-avatar">
							<up-image :src="patient._avatarLoadError ? defaultImg : getPatientAvatar(patient)" width="80rpx" height="80rpx" mode="aspectFill" @error="handlePatientAvatarError(patient)"></up-image>
						   </view>
						   <view class="name">
							  <view class="real">{{ patient.realName}}</view>
							  <view class="nick" v-if="patient.nickname">{{ patient.nickname}}</view>
						   </view>
						</view>
						
						<view class="patient-checkbox" @click.stop="togglePatientSelection(gi, patient, index)">
							<view class="checkbox" :class="{ 'checked': isPatientSelected(gi, patient, index) }">
								<uni-icons v-if="isPatientSelected(gi, patient, index)" type="checkmarkempty" color="#8B2316" size="16"></uni-icons>
							</view>
						</view>
						
					</view>
				</view>
			</view>
			<empty v-if="groups.length == 0" :emptyDesc="'暂无分组'" />
		</scroll-view>
		<!-- 底部操作栏 -->
		<view class="bottom-bar">
			<view class="clear-btn" @click="clearSelection">清空选择</view>
		</view>
	</view>
</template>

<script setup>
import { ref, computed, onMounted,nextTick} from 'vue';
import { onShow,onLoad } from "@dcloudio/uni-app";
import upImg from "@/static/triangle_green_theme.png"
import downImg from "@/static/triangle_normal.png"
import groupRightImg from "@/static/groupright_big.png"
import groupDownImg from "@/static/groupup_big.png"
import defaultImg from "@/static/default.png"
import api from '@/api/api.js';
import docUrl from '@/utils/docUrl'
import dayjs from 'dayjs'
import navTo from '@/utils/navTo.js'
import empty from "@/components/empty/empty.vue"
const list_sort = ref(0);
const group_sort = ref(0);

// 分组数据与展开状态
const groups = ref([]);
const openGroups = ref({});
// 选中的分组状态
const selectedGroups = ref({});
// 选中的患者状态：以分组索引为key，值为Set或索引Map
const selectedPatients = ref({});

const formatYMD = (val) => {
	if (!val) return '';
	const d = dayjs(val);
	return d.isValid() ? d.format('YYYY-MM-DD') : '';
};

// 排序栏标题
const groupSortTitle = computed(() => group_sort.value === 0 ? '按首字母' : '分组人数');
const innerSortTitle = computed(() => list_sort.value === 0 ? '按首字母' : '随访时间');

// 计算选中的分组数量
const selectedGroupCount = computed(() => {
	return Object.values(selectedGroups.value).filter(Boolean).length;
});

// 计算选中的患者数量（去重）
const getPatientUniqueId = (p) => {
    return (p && (p.uuid || p.patientUuid || p.id || p.userId)) || '';
};

const selectedPatientCount = computed(() => {
    const idSet = new Set();
    groups.value.forEach((group, gi) => {
        const map = selectedPatients.value[gi] || {};
        (group.patientList || []).forEach((patient, pi) => {
            if (map[pi]) {
                const uid = getPatientUniqueId(patient);
                if (uid) idSet.add(uid);
            }
        });
    });
    return idSet.size;
});

// 合计数量：只计算去重后的患者数量
const totalSelectedCount = computed(() => selectedPatientCount.value);
const from = ref('');
onLoad((options) => {
	uni.showLoading({
		title: '加载中...',
		mask: true
	});
	fetchGroupList();
	if(options.from){
		from.value = options.from;
	}
});

const fetchGroupList = async () => {
	const res = await api.groupList({
		list_sort:list_sort.value,
		page:1,
		pageSize:10,
		group_sort:group_sort.value
	});
	if(res.code === 200){
		groups.value = Array.isArray(res.data) ? res.data : [];
		// 初始化展开状态：默认收起
		openGroups.value = {};
		groups.value.forEach((group, idx) => {
			openGroups.value[idx] = false;
			// 初始化患者选择Map，避免未定义
			if (!selectedPatients.value[idx]) selectedPatients.value[idx] = {};
			// 若组选中但患者为空，则保持组选中；否则按患者是否全选同步组选中状态
			updateGroupSelectionByPatients(idx);
		});
		nextTick(() => {
			uni.hideLoading();
		});
	}
};

const toggleGroup = (idx) => {
	openGroups.value[idx] = !openGroups.value[idx];
};

const toggleGroupSelection = (idx) => {
	const group = groups.value[idx] || {};
	const patients = group.patientList || [];
	const willSelect = !isGroupSelected(idx);
	// 设置组选中状态
	selectedGroups.value[idx] = willSelect;
	// 同步该组下的患者选中状态
	if (!selectedPatients.value[idx]) selectedPatients.value[idx] = {};
	patients.forEach((_, pi) => {
		selectedPatients.value[idx][pi] = willSelect;
	});
};

const isPatientSelected = (gi, patient, index) => {
	const groupSelectedMap = selectedPatients.value[gi] || {};
	return !!groupSelectedMap[index];
};

const togglePatientSelection = (gi, patient, index) => {
	if (!selectedPatients.value[gi]) selectedPatients.value[gi] = {};
	selectedPatients.value[gi][index] = !selectedPatients.value[gi][index];
	// 若组内所有患者都被勾选，则自动勾选组；否则取消组勾选
	updateGroupSelectionByPatients(gi);
};

const isGroupSelected = (gi) => {
	// 优先：若显式设置了组选中状态，且为true，直接认为选中
	if (selectedGroups.value[gi]) return true;
	// 否则根据患者是否全选判断
	const group = groups.value[gi] || {};
	const patients = group.patientList || [];
	if (patients.length === 0) return !!selectedGroups.value[gi];
	const map = selectedPatients.value[gi] || {};
	return patients.every((_, pi) => !!map[pi]);
};

const updateGroupSelectionByPatients = (gi) => {
	const group = groups.value[gi] || {};
	const patients = group.patientList || [];
	const map = selectedPatients.value[gi] || {};
	if (patients.length === 0) return;
	selectedGroups.value[gi] = patients.every((_, pi) => !!map[pi]);
};

const editGroup = (group) => {
	navTo({
		url: `/pages_app/groupEdit/groupEdit?uuid=${group.uuid}`
	})
};

// 分组排序弹窗状态
const showGroupSort = ref(false);
const selectedGroupSort = ref('letter'); // letter | count

// 组内排序弹窗状态
const showInnerSort = ref(false);
const selectedInnerSort = ref('letter');

// 待分组展开/收起
const showPending = ref(false);

const toggleGroupSort = () => {
  showGroupSort.value = !showGroupSort.value;
  if (showGroupSort.value) showInnerSort.value = false;
};
const closeGroupSort = () => {
  showGroupSort.value = false;
};

const chooseGroupSort = (type) => {
	selectedGroupSort.value = type;
	// 修改接口字段：按首字母=0，分组人数=1
	group_sort.value = type === 'letter' ? 0 : 1;
	closeGroupSort();
	fetchGroupList();
};
const confirmGroup = () => {
	// 收集已选患者，并做去重
	if(totalSelectedCount.value > 200){
		uni.showToast({ title: '选择人数不能超过200', icon: 'none' });
		return;
	}
	const idSet = new Set();
	const dedupPatients = [];
	groups.value.forEach((group, gi) => {
		const map = selectedPatients.value[gi] || {};
		(group.patientList || []).forEach((patient, pi) => {
			if (map[pi]) {
				const uid = getPatientUniqueId(patient);
				if (uid && !idSet.has(uid)) {
					idSet.add(uid);
					dedupPatients.push(patient);
				}
			}
		});
	});

	if (dedupPatients.length === 0) {
		uni.showToast({ title: '请至少选择1个患者', icon: 'none' });
		return;
	}

    try {
		if(from.value){
			uni.$emit('selectedChatPatientsSingle', { patients: dedupPatients });
			uni.navigateBack();
		}else{
			uni.navigateTo({
            url: '/pages_chat/groupSend/groupSend',
            success: (res) => {
                try {
                    uni.$emit('selectedChatPatients', { patients: dedupPatients });
                } catch (emitErr) {
                    console.error('传递已选患者失败', emitErr);
                    uni.showToast({ title: '传递失败，请重试', icon: 'none' });
                }
            }
        });
		}
        
    } catch (e) {
        console.error('跳转失败', e);
        uni.showToast({ title: '跳转失败，请重试', icon: 'none' });
    }
}
const toggleInnerSort = () => {
  showInnerSort.value = !showInnerSort.value;
  if (showInnerSort.value) showGroupSort.value = false;
};

const closeInnerSort = () => {
  showInnerSort.value = false;
};

const chooseInnerSort = (type) => {
	selectedInnerSort.value = type;
	// 组内排序：按首字母=0，随访时间=1
	list_sort.value = type === 'letter' ? 0 : 1;
	closeInnerSort();
	fetchGroupList();
};

// 方法
const goBack = () => {
	uni.navigateBack();
};

const createNew = () => {
	uni.showToast({
		title: '跳转到新建分组页面',
		icon: 'none'
	});
	// 这里可以跳转到新建分组页面
};

// 清空选择
const clearSelection = () => {
	selectedGroups.value = {};
	selectedPatients.value = {};
};

const getPatientAvatar = (patient) => {
	if (!patient) return defaultImg;
	return patient.photo ? (docUrl + patient.photo) : defaultImg;
};

const handlePatientAvatarError = (patient) => {
	if (!patient) return;
	patient._avatarLoadError = true;
};

</script>

<style lang="scss" scoped>
.namebox{
	display: flex;
   align-items: center;
   .name{
	margin-left: 16rpx;
   }
   .real{
	 color: #333;
	 font-size: 28rpx;
   }
   .nick{
		color:#666;
		font-size: 26rpx;
		margin-top: 2rpx;
   }
}
.patient-group-page {
	min-height: 100vh;
	background-color: #f5f5f5;
}

/* 弹窗样式 */
.popup-mask {
	position: fixed;
	top: 220rpx; /* 位于筛选栏下方 */
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0,0,0,0.3);
	z-index: 8;
}

.popup-panel {
	position: fixed;
	top: 220rpx; /* 紧贴筛选栏 */
	left: 0;
	right: 0;
	background: #fff;
	z-index: 10;
	box-shadow: 0 6rpx 20rpx rgba(0,0,0,0.08);
}

.popup-item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 28rpx 30rpx;
	font-size: 30rpx;
	color: #333;
}

.popup-divider {
	height: 2rpx;
	background: #eaeaea;
}

.popup-item.active .item-text {
	color: #8B2316;
}
.save-text{ 
	margin-top: -20rpx;
	color:#8B2316; 
	font-size: 30rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	
 }
.status-bar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 10rpx 30rpx;
	background-color: #ffffff;
	font-size: 24rpx;
	color: #333;
	
	.status-left {
		display: flex;
		align-items: center;
		gap: 20rpx;
		
		.time {
			font-weight: 500;
		}
		
		.app-icons {
			display: flex;
			gap: 10rpx;
			
			.app-icon {
				width: 24rpx;
				height: 24rpx;
				border-radius: 4rpx;
				
				&.weibo {
					background-color: #ff8200;
				}
				
				&.taobao {
					background-color: #ff6a00;
				}
				
				&.xiaohongshu {
					background-color: #ff2442;
				}
			}
		}
	}
	
	.status-right {
		display: flex;
		align-items: center;
		gap: 15rpx;
		
		.network {
			color: #666;
		}
		
		.signal-icon {
			width: 32rpx;
			height: 20rpx;
			background-color: #333;
			border-radius: 2rpx;
		}
		
		.battery-text {
			font-size: 20rpx;
			color: #333;
		}
		
		.battery {
			width: 40rpx;
			height: 20rpx;
			border: 2rpx solid #333;
			border-radius: 4rpx;
			background-color: #4caf50;
			position: relative;
			
			&::after {
				content: '';
				position: absolute;
				right: -6rpx;
				top: 6rpx;
				width: 4rpx;
				height: 8rpx;
				background-color: #333;
				border-radius: 0 2rpx 2rpx 0;
			}
		}
	}
}

.header {
	display: flex;
	align-items: center;
	padding: 20rpx 30rpx;
	background-color: #ffffff;
	border-bottom: 1rpx solid #f0f0f0;
	
	.back-btn {
		padding: 10rpx;
	}
	
	.title {
		flex: 1;
		text-align: center;
		font-size: 36rpx;
		font-weight: normal;
		color: #ff0000;
		margin-right: 60rpx; // 为了保持标题居中
	}
	
	.new-btn {
		padding: 10rpx;
		
		.new-text {
			font-size: 28rpx;
			color: #ff0000;
		}
	}
}

.filter-sort-bar {
	display: flex;
	align-items: center;
	justify-content:center;
	padding: 20rpx 30rpx;
	background-color: #ffff;
	position: fixed;
	top: 180rpx;
	left: 0;
	right: 0;
	z-index: 9;
	border-bottom: 1rpx solid #f0f0f0;
	.imgbox{
		width: 32rpx;
		margin-top: -10rpx;
	}
	.sort-section {
		display: flex;
		align-items: center;
		gap: 10rpx;
		
		.sort-label {
			font-size: 28rpx;
			color: #333;
		}
		
		.sort-icon.down {
			width: 0;
			height: 0;
			border-left: 8rpx solid transparent;
			border-right: 8rpx solid transparent;
			border-top: 12rpx solid #999;
		}
	}
	
	.divider {
		width: 2rpx;
		height: 40rpx;
		background-color: #e0e0e0;
		margin: 0 80rpx;
	}
	
	.current-sort {
		display: flex;
		align-items: center;
		gap: 10rpx;
		
		.sort-text {
			font-size: 28rpx;
			color: #333;
		}
		
		.sort-icon.up {
			width: 0;
			height: 0;
			border-left: 8rpx solid transparent;
			border-right: 8rpx solid transparent;
			border-bottom: 12rpx solid #999;
			
			&.active {
				border-bottom-color: #ff0000;
			}
		}
	}
}

.patient-list-section {
	top:calc(var(--status-bar-height) + 44px);
	width:100%;
	bottom:144rpx; // 预留底部操作栏高度
	position: fixed;
	background-color: #ffffff;
	
	.section-title {
		padding: 30rpx 30rpx 20rpx;
		font-size: 32rpx;
		width: 100%;
		box-sizing: border-box;
		font-weight: normal;
		display: flex;
		color: #333;
		border-bottom: 1rpx solid #f0f0f0;
		align-items: center;
		justify-content: space-between;
		.left{
			display:flex;
			align-items:center;
		}
		.imgbox{
			&.active{
				margin-top: -20rpx;
			}
			margin-right: 8rpx;
		}
		.right-checkbox{
			display:flex;
			align-items:center;
			.checkbox{
				width: 40rpx;
				height: 40rpx;
				border: 2rpx solid #ddd;
				border-radius: 8rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				background-color: #fff;
				transition: all 0.3s ease;
				
				&.checked{
					border-color: #8B2316;
				}
			}
		}
	}
	
	.patient-list {
		// 滚动视图样式
		&::-webkit-scrollbar {
			display: none;
		}
		
		.patient-item {
			display: flex;
			align-items: center;
			justify-content: space-between;
			gap: 20rpx;
			padding: 30rpx 40rpx;
			border-bottom: 1rpx solid #f0f0f0;
			
			&:last-child {
				border-bottom: none;
			}
			
			.patient-checkbox{
				margin-right: 8rpx;
				.checkbox{
					width: 40rpx;
					height: 40rpx;
					border: 2rpx solid #ddd;
					border-radius: 8rpx;
					display: flex;
					align-items: center;
					justify-content: center;
					background-color: #fff;
					transition: all 0.3s ease;
					&.checked{ border-color: #8B2316; }
				}
			}
			
			.patient-avatar {
				width: 80rpx;
				height: 80rpx;
				border-radius: 12rpx;
				overflow: hidden;
			}
			
			.patient-info {
				flex: 1;
				
				.patient-name {
					font-size: 32rpx;
					color: #333;
					margin-top: 24rpx;
				}
				
				.follow-up-time {
					font-size: 24rpx;
					color: #999;
					display: flex;
					justify-content: flex-end;
				}
			}
		}
	}
}

.bottom-bar{
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	background: #fff;
	box-shadow: 0 -6rpx 20rpx rgba(0,0,0,0.06);
	padding:30rpx;
	display: flex;
	justify-content: flex-end;
	.align-right{justify-content:flex-end;}

	.clear-btn{
	    width: 100%;
		
		height: 80rpx;
		line-height: 80rpx;
		text-align: center;
		border-radius: 12rpx;
		border: 2rpx solid #8B2316;
		color: #8B2316;
		font-size: 28rpx;
	}
}
</style>
