<template>
	<view class="app-container">
		<!-- 搜索区（仅非学生角色显示） -->
		<view class="fixed-search-wrap" v-if="roleGroup != '学生'">
			<view class="search-content">
				<view class="search-card">
					<!-- 姓名搜索输入框 -->
					<view class="search-row">
						<uni-icons type="search" size="28rpx" color="#1890FF" class="search-icon"></uni-icons>
						<input v-model="queryParams.studentName" placeholder="输入学生姓名搜索" @input="handleQuery"
							class="search-input" />
					</view>

					<!-- 筛选行：学号/学院/班级 -->
					<view class="filter-row">
						<view class="filter-item">
							<text class="filter-label">学号</text>
							<input class="picker-content" v-model="queryParams.studentNo" type="text"
								placeholder="请输入" />
						</view>
						<view class="filter-item">
							<text class="filter-label">学院</text>
							<input class="picker-content" v-model="queryParams.deptName" type="text"
								placeholder="请输入" />
						</view>
						<view class="filter-item">
							<text class="filter-label">班级</text>
							<input class="picker-content" v-model="queryParams.className" type="text"
								placeholder="请输入" />
						</view>
					</view>

					<!-- 操作按钮 -->
					<view class="action-row">
						<button class="reset-btn" @click="resetQuery">
							<uni-icons type="clear" size="24rpx" color="#1890FF" class="btn-icon"></uni-icons>
							重置
						</button>
						<button class="search-btn" @click="handleQuery">
							<uni-icons type="search" size="24rpx" color="#fff" class="btn-icon"></uni-icons>
							搜索
						</button>
					</view>
				</view>
			</view>
		</view>

		<!-- 数据列表滚动容器 -->
		<scroll-view class="list-container" scroll-y @scrolltolower="handleLoadMore" lower-threshold="50" enhanced
			:show-scrollbar="false">
			<!-- 初始加载状态 -->
			<uni-load-more :status="loading ? 'loading' : 'done'" v-if="loading" class="loading-wrap"></uni-load-more>

			<!-- 空数据状态 -->
			<view class="empty-state" v-if="!loading && !hasData">
				<uni-icons type="empty" size="80" color="#c0c4cc"></uni-icons>
				<text class="empty-text">暂无外宿申请数据</text>
				<text class="empty-tip" v-if="roleGroup.includes('学生')">点击右下角"+号"按钮提交新申请</text>
			</view>

			<!-- 数据列表 -->
			<view class="card-list" v-if="!loading && hasData">
				<view class="apply-card" v-for="(item, index) in validDataList" :key="index" hover-class="card-hover"
					:hover-stop-propagation="true">
					<!-- 卡片头部 -->
					<view class="card-header">
						<view class="apply-no">
							<text class="label-text">申请编号：</text>
							<text class="no-text">{{ getSafeValue(item, 'applyNo', '无') }}</text>
						</view>
						<view class="status-wrap">
							<view class="status-label" :class="getStatusClass(item)">
								{{ getStatusText(item) }}
							</view>
							<view class="valid-label"
								:class="getSafeValue(item, 'isValid') == 1 ? 'valid-success' : 'valid-info'">
								{{ getSafeValue(item, 'isValid') == 1 ? '有效' : '到期' }}
							</view>
						</view>
					</view>

					<!-- 卡片主体折叠面板 -->
					<uni-collapse accordion v-model="item.activeCollapse">
						<uni-collapse-item title="基本信息" name="basic" class="collapse-item">
							<view class="info-grid">
								<view class="info-item"><text class="label">学号：</text><text
										class="value">{{ getSafeValue(item, 'studentNo', '-') }}</text></view>
								<view class="info-item"><text class="label">姓名：</text><text
										class="value">{{ getSafeValue(item, 'studentName', '-') }}</text></view>
								<view class="info-item"><text class="label">性别：</text><text
										class="value">{{ getSafeValue(item, 'gender') == 1 ? '男' : getSafeValue(item, 'gender') == 0 ? '女' : '-' }}</text>
								</view>
								<view class="info-item"><text class="label">出生年月：</text><text
										class="value">{{ parseTime(getSafeValue(item, 'birthDate')) || '-' }}</text>
								</view>
								<view class="info-item"><text class="label">学院：</text><text
										class="value">{{ getSafeValue(item, 'deptName', '-') }}</text></view>
								<view class="info-item"><text class="label">专业：</text><text
										class="value">{{ getSafeValue(item, 'majorName', '-') }}</text></view>
								<view class="info-item"><text class="label">班级：</text><text
										class="value">{{ getSafeValue(item, 'className', '-') }}</text></view>
								<view class="info-item"><text class="label">辅导员：</text><text
										class="value">{{ getSafeValue(item, 'teacherName', '-') }}</text></view>
								<view class="info-item"><text class="label">原宿舍号：</text><text
										class="value">{{ getSafeValue(item, 'originalDormitory', '-') }}</text></view>
								<view class="info-item">
									<text class="label">住宿费状态：</text>
									<text class="value">
										<view class="fee-label"
											:class="getSafeValue(item, 'accommodationFeeStatus') === 1 ? 'fee-success' : 'fee-info'">
											{{ getSafeValue(item, 'accommodationFeeStatus') === 1 ? '已交' : '未交' }}
										</view>
									</text>
								</view>
								<view class="info-item"><text class="label">宿费交纳：</text><text
										class="value">{{ getSafeValue(item, 'accommodationFee', '-') }}</text></view>
							</view>
						</uni-collapse-item>

						<uni-collapse-item title="外宿信息" name="outside" class="collapse-item">
							<view class="info-form">
								<view class="form-item"><text class="label">外宿原因：</text><text
										class="value">{{ getSafeValue(item, 'applyReason', '-') }}</text></view>
								<view class="form-item"><text class="label">外宿地址：</text><text
										class="value">{{ (getSafeValue(item, 'address', '') + ' ' + getSafeValue(item, 'outsideAddress', '')) || '-' }}</text>
								</view>
								<view class="form-item">
									<text class="label">外宿时间：</text>
									<text class="value">{{ parseTime(getSafeValue(item, 'startDate')) || '-' }}
										<text class="split-text">至</text>
										{{ parseTime(getSafeValue(item, 'endDate')) || '-' }}
									</text>
								</view>
								<view class="form-item"><text class="label">紧急联系人：</text><text
										class="value">{{ getSafeValue(item, 'emergencyContact', '-') }}
										({{ getSafeValue(item, 'emergencyPhone', '-') }})</text></view>
								<view class="form-item"><text class="label">家长意见：</text><text
										class="value">{{ getSafeValue(item, 'parentOpinion') == 1 ? '同意' : getSafeValue(item, 'parentOpinion') == 0 ? '不同意' : '-' }}</text>
								</view>
								<view class="form-item"><text class="label">家长联系方式：</text><text
										class="value">{{ getSafeValue(item, 'parentPhone', '-') }}</text></view>
							</view>
						</uni-collapse-item>

						<uni-collapse-item title="审批记录" name="approval" class="collapse-item">
							<view class="approval-list"
								v-if="getSafeValue(item, 'outsideAccommodationApprovals', []).length > 0">
								<view class="approval-item"
									v-for="(approval, idx) in getSafeValue(item, 'outsideAccommodationApprovals', [])"
									:key="idx">
									<text
										class="approval-node">{{ getSafeValue(approval, 'approvalNode', '未知节点') }}：</text>
									<text class="approval-result"
										:class="getSafeValue(approval, 'approvalResult') == 1 ? 'result-pass' : 'result-reject'">
										{{ getSafeValue(approval, 'approvalResult') == 1 ? '通过' : '驳回' }}
									</text>
									<text class="approval-time"
										v-if="getSafeValue(approval, 'approvalTime')">{{ parseTime(getSafeValue(approval, 'approvalTime')) }}</text>
									<text class="approval-remark"
										v-if="getSafeValue(approval, 'approvalRemark')">备注：{{ getSafeValue(approval, 'approvalRemark') }}</text>
								</view>
							</view>
							<view class="empty-approval" v-else>暂无审批记录</view>
						</uni-collapse-item>
					</uni-collapse>

					<!-- 卡片操作区 -->
					<view class="card-actions">
						<uni-button type="text" size="mini" @click="detail(item)" class="detail-btn"
							:disabled="!getSafeValue(item, 'id')">
							<uni-icons type="info" size="14" class="mr-5"></uni-icons>查看详情
						</uni-button>
					</view>
				</view>
			</view>

			<!-- 加载更多状态 -->
			<view class="load-more-wrap" v-if="hasData">
				<uni-load-more :status="loadingMore ? 'loading' : (hasMore ? 'more' : 'nomore')"
					:content-text="loadMoreText"></uni-load-more>
			</view>
		</scroll-view>
		<!-- 添加外宿申请按钮 -->
		<view class="add" @click="addOutsideAccommodation">+</view>
	</view>
</template>

<script>
	import {
		listOutsideAccommodationApply
	} from "@/api/dms/outsideAccommodation/outsideAccommodationApply";
	import {
		getUserProfile
	} from '@/api/system/user';

	export default {
		name: "OutsideAccommodationApplyList",
		data() {
			return {
				// 加载状态
				loading: true,
				loadingMore: false,
				hasMore: true,
				// 总数据量
				totalCount: 0,
				// 原始数据
				outsideAccommodationApplyList: [],
				// 查询参数
				queryParams: {
					pageNum: 1,
					pageSize: 5,
					studentNo: null,
					studentName: null,
					deptName: null,
					className: null,
					teacherName: null
				},
				// 用户角色
				roleGroup: '',
				user: {},
				// 加载更多文本
				loadMoreText: {
					contentdown: '上拉加载更多',
					contentrefresh: '正在加载...',
					contentnomore: '没有更多数据了'
				}
			};
		},
		computed: {
			// 过滤后的有效数据列表
			validDataList() {
				return this.outsideAccommodationApplyList.filter(item => {
					return item !== null && item !== undefined && typeof item === 'object';
				}).map(item => {
					if (!item.hasOwnProperty('activeCollapse')) {
						item.activeCollapse = 'basic';
					}
					return item;
				});
			},
			// 是否有有效数据
			hasData() {
				return this.validDataList.length > 0;
			}
		},
		onLoad() {
			this.getUser();
		},
		methods: {
			/** 安全取值方法 */
			getSafeValue(obj, key, defaultValue = '') {
				if (!obj || typeof obj !== 'object') return defaultValue;
				return obj[key] !== undefined && obj[key] !== null ? obj[key] : defaultValue;
			},

			/** 获取状态样式类 */
			getStatusClass(item) {
				const rejectInfo = this.getRejectInfo(item);
				if (rejectInfo.isReject) {
					return 'status-error';
				}
				const status = this.getSafeValue(item, 'status');
				const typeMap = {
					'0': 'status-info',
					'1': 'status-warning',
					'2': 'status-warning',
					'3': 'status-warning',
					'4': 'status-warning',
					'5': 'status-success'
				};
				return typeMap[status] || 'status-default';
			},

			/** 获取驳回信息 */
			getRejectInfo(item) {
				const approvalList = this.getSafeValue(item, 'outsideAccommodationApprovals', []);
				if (!Array.isArray(approvalList) || approvalList.length === 0) {
					return {
						isReject: false,
						rejectText: ''
					};
				}

				const rejectItem = approvalList.find(approval => {
					return this.getSafeValue(approval, 'approvalResult') === 0;
				});

				if (rejectItem) {
					const nodeName = this.getSafeValue(rejectItem, 'approvalNode', '未知').replace('审批', '');
					return {
						isReject: true,
						rejectText: `${nodeName}驳回`
					};
				} else {
					return {
						isReject: false,
						rejectText: ''
					};
				}
			},

			/** 获取状态文本 */
			getStatusText(item) {
				const rejectInfo = this.getRejectInfo(item);
				if (rejectInfo.isReject) {
					return rejectInfo.rejectText;
				}

				const status = this.getSafeValue(item, 'status');
				const statusMap = {
					'0': '待提交',
					'1': '待辅导员审批',
					'2': '待学院书记审批',
					'3': '待学工处审批',
					'4': '待学校领导审批',
					'5': '审核通过'
				};
				return statusMap[status] || '未知状态';
			},

			/** 时间格式化 */
			parseTime(time, format = '{y}-{m}-{d}') {
				if (!time) return '';

				try {
					const date = new Date(time);
					if (isNaN(date.getTime())) return '';

					const year = date.getFullYear();
					const month = (date.getMonth() + 1).toString().padStart(2, '0');
					const day = date.getDate().toString().padStart(2, '0');
					return format.replace('{y}', year).replace('{m}', month).replace('{d}', day);
				} catch (error) {
					return '';
				}
			},

			/** 查询数据 */
			getList(isRefresh = false) {
				if (isRefresh) {
					this.loading = true;
					this.hasMore = true;
					this.queryParams.pageNum = 1;
					this.outsideAccommodationApplyList = [];
				} else {
					this.loadingMore = true;
				}

				listOutsideAccommodationApply(this.queryParams).then(response => {
					const res = response || {};
					const newData = Array.isArray(res.rows) ? res.rows : [];
					this.totalCount = Number(res.total) || 0;

					if (isRefresh) {
						this.outsideAccommodationApplyList = newData;
					} else {
						this.outsideAccommodationApplyList = [...this.outsideAccommodationApplyList, ...newData];
					}

					// 更新状态
					this.loading = false;
					this.loadingMore = false;
					this.hasMore = this.outsideAccommodationApplyList.length < this.totalCount;

				}).catch((error) => {
					console.error('数据加载失败:', error);
					this.loading = false;
					this.loadingMore = false;
					uni.showToast({
						title: '数据加载失败',
						icon: 'none'
					});
				});
			},

			/** 获取用户信息 */
			getUser() {
				getUserProfile().then(response => {
					const res = response || {};
					this.user = res.data || {};
					this.roleGroup = res.roleGroup || '';

					// 填充查询条件
					if (this.roleGroup.includes("学生")) {
						this.queryParams.studentName = this.user.nickName || '';
					} else if (this.roleGroup.includes("辅导员")) {
						this.queryParams.teacherName = this.user.nickName || '';
					} else if (this.roleGroup.includes("二级学院")) {
						this.queryParams.deptName = this.user.dept?.deptName || '';
					}

					this.getList(true);
				}).catch((error) => {
					console.error('用户信息获取失败:', error);
					this.loading = false;
					uni.showToast({
						title: '用户信息加载失败',
						icon: 'none'
					});
				});
			},

			/** 搜索 */
			handleQuery() {
				this.getList(true);
			},

			/** 重置 */
			resetQuery() {
				this.queryParams = {
					pageNum: 1,
					pageSize: 5,
					studentNo: null,
					studentName: null,
					deptName: null,
					className: null,
					teacherName: null
				};

				// 重新填充角色相关的默认查询条件
				if (this.roleGroup.includes("学生")) {
					this.queryParams.studentName = this.user.nickName || '';
				} else if (this.roleGroup.includes("辅导员")) {
					this.queryParams.teacherName = this.user.nickName || '';
				} else if (this.roleGroup.includes("二级学院")) {
					this.queryParams.deptName = this.user.dept?.deptName || '';
				}

				this.getList(true);
			},

			/** 加载更多 */
			handleLoadMore() {
				if (this.loadingMore || !this.hasMore) return;

				this.queryParams.pageNum += 1;
				this.getList(false);
			},

			/** 查看详情 */
			detail(item) {
				const id = this.getSafeValue(item, 'id');
				if (!id) {
					uni.showToast({
						title: '数据异常，无法查看详情',
						icon: 'none'
					});
					return;
				}
				uni.navigateTo({
					url: `/pages/dormitory/outsideAccommodation/applicationForm?id=${id}`
				});
			},
			// 跳转添加页面
			addOutsideAccommodation() {
				if (this.roleGroup === "学生") {
					if (this.outsideAccommodationApplyList.length > 0) {
						uni.showToast({
							title: '请勿重复提交',
							icon: 'none'
						});
						return
					}
				}
				uni.navigateTo({
					url: `/pages/dormitory/outsideAccommodation/applicationForm`
				})
			},
		}
	};
</script>

<style scoped>
	.add {
		position: fixed;
		bottom: 50rpx;
		right: 50rpx;
		width: 90rpx;
		height: 90rpx;
		border-radius: 50%;
		background-color: #1890FF;
		color: white;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 60rpx;
		box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.3);
		z-index: 99;
	}

	/* 全局样式 */
	.app-container {
		padding: 20rpx;
		background-color: #f5f7fa;
		min-height: 100vh;
	}

	.mr-5 {
		margin-right: 5px;
	}

	/* 搜索区样式 */
	.fixed-search-wrap {
		z-index: 90;
		background-color: #fff;
		border-bottom: 1px solid #eee;
		margin-bottom: 15rpx;
	}

	.search-content {
		transition: all 0.3s ease;
	}

	.search-card {
		padding: 20rpx;
	}

	.search-row {
		display: flex;
		align-items: center;
		background-color: #f5f7fa;
		border-radius: 60rpx;
		padding: 14rpx 20rpx;
		margin-bottom: 24rpx;
	}

	.search-icon {
		margin-right: 12rpx;
	}

	.search-input {
		flex: 1;
		font-size: 28rpx;
		color: #333;
	}

	.filter-row {
		display: flex;
		flex-wrap: wrap;
		gap: 16rpx;
		margin-bottom: 24rpx;
	}

	.filter-item {
		flex: 1;
		min-width: 120rpx;
		display: flex;
		flex-direction: column;
		gap: 8rpx;
	}

	.filter-label {
		font-size: 24rpx;
		color: #666;
		padding-left: 4rpx;
	}

	.picker-content {
		display: flex;
		align-items: center;
		font-size: 26rpx;
		color: #333;
		padding: 14rpx 16rpx;
		background-color: #f5f7fa;
		border-radius: 12rpx;
		height: 60rpx;
		box-sizing: border-box;
	}

	.action-row {
		display: flex;
		gap: 16rpx;
	}

	.reset-btn,
	.search-btn {
		flex: 1;
		height: 72rpx;
		line-height: 72rpx;
		border-radius: 36rpx;
		font-size: 28rpx;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.reset-btn {
		background-color: #fff;
		color: #1890FF;
		border: 1px solid #1890FF;
	}

	.search-btn {
		background-color: #1890FF;
		color: #fff;
		border: none;
	}

	.btn-icon {
		margin-right: 6rpx;
	}

	/* 列表滚动容器 */
	.list-container {
		width: 100%;
		height: calc(100vh - 380rpx);
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
	}

	.loading-wrap {
		padding: 60rpx 0;
	}

	/* 加载更多区域 */
	.load-more-wrap {
		padding: 30rpx 0;
		text-align: center;
		height: 80rpx;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	/* 空数据状态 */
	.empty-state {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		padding: 120rpx 0;
		color: #909399;
	}

	.empty-text {
		margin-top: 30rpx;
		font-size: 32rpx;
	}

	.empty-tip {
		margin-top: 16rpx;
		font-size: 26rpx;
		color: #c0c4cc;
	}

	/* 卡片列表 */
	.card-list {
		display: flex;
		flex-direction: column;
		gap: 24rpx;
	}

	/* 申请卡片 */
	.apply-card {
		background-color: #fff;
		border-radius: 16rpx;
		overflow: hidden;
		box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
		transition: all 0.3s ease;
	}

	.card-hover {
		transform: translateY(-4rpx);
		box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.1);
	}

	/* 卡片头部 */
	.card-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 24rpx;
		background: linear-gradient(135deg, #e8f4f8 0%, #f0f8fb 100%);
		border-bottom: 1rpx solid #f2f2f2;
	}

	.apply-no {
		display: flex;
		align-items: center;
	}

	.label-text {
		font-size: 26rpx;
		color: #606266;
		margin-right: 8rpx;
	}

	.no-text {
		font-size: 28rpx;
		font-weight: 600;
		color: #303133;
	}

	.status-wrap {
		display: flex;
		align-items: center;
		gap: 10rpx;
	}

	/* 状态标签样式 */
	.status-label {
		height: 44rpx;
		line-height: 44rpx;
		font-size: 24rpx;
		padding: 0 16rpx;
		border-radius: 22rpx;
		color: #fff;
	}

	.status-success {
		background-color: #67c23a;
	}

	.status-warning {
		background-color: #e6a23c;
	}

	.status-error {
		background-color: #f56c6c;
	}

	.status-info {
		background-color: #909399;
	}

	.status-default {
		background-color: #409eff;
	}

	/* 有效/到期标签 */
	.valid-label {
		height: 44rpx;
		line-height: 44rpx;
		font-size: 22rpx;
		padding: 0 12rpx;
		border-radius: 22rpx;
		color: #fff;
	}

	.valid-success {
		background-color: #67c23a;
	}

	.valid-info {
		background-color: #909399;
	}

	/* 住宿费状态标签 */
	.fee-label {
		display: inline-block;
		height: 36rpx;
		line-height: 36rpx;
		font-size: 22rpx;
		padding: 0 12rpx;
		border-radius: 18rpx;
		color: #fff;
	}

	.fee-success {
		background-color: #67c23a;
	}

	.fee-info {
		background-color: #f56c6c;
	}

	/* 折叠面板 */
	.collapse-item {
		--uni-collapse-item-header-padding: 24rpx;
		--uni-collapse-item-content-padding: 0;
		--uni-collapse-item-header-font-size: 28rpx;
		--uni-collapse-item-header-color: #303133;
	}

	/* 信息网格 */
	.info-grid {
		display: flex;
		flex-wrap: wrap;
		padding: 24rpx;
		gap: 20rpx;
	}

	.info-grid .info-item {
		width: calc(50% - 10rpx);
		display: flex;
		align-items: center;
		font-size: 26rpx;
		line-height: 1.6;
	}

	/* 信息表单 */
	.info-form {
		padding: 24rpx;
	}

	.info-form .form-item {
		display: flex;
		flex-direction: column;
		margin-bottom: 24rpx;
		font-size: 26rpx;
		line-height: 1.6;
	}

	.info-form .form-item:last-child {
		margin-bottom: 0;
	}

	.split-text {
		margin: 0 10rpx;
		color: #c0c4cc;
	}

	/* 标签和值样式 */
	.label {
		color: #606266;
		margin-right: 12rpx;
		font-weight: 500;
		min-width: 120rpx;
	}

	.info-form .label {
		margin-bottom: 8rpx;
		font-size: 26rpx;
	}

	.value {
		color: #303133;
		flex: 1;
	}

	/* 审批记录 */
	.approval-list {
		padding: 24rpx;
	}

	.approval-item {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		padding: 12rpx 0;
		border-bottom: 1rpx dashed #f2f2f2;
		font-size: 26rpx;
	}

	.approval-item:last-child {
		border-bottom: none;
	}

	.approval-node {
		color: #606266;
		margin-right: 8rpx;
	}

	.approval-result {
		margin-right: 16rpx;
	}

	.result-pass {
		color: #67c23a;
	}

	.result-reject {
		color: #f56c6c;
	}

	.approval-time {
		color: #909399;
		font-size: 24rpx;
		margin-right: 16rpx;
	}

	.approval-remark {
		color: #303133;
		font-size: 24rpx;
		width: 100%;
		margin-top: 8rpx;
	}

	.empty-approval {
		padding: 24rpx;
		text-align: center;
		color: #909399;
		font-size: 26rpx;
	}

	/* 卡片操作区 */
	.card-actions {
		display: flex;
		justify-content: flex-end;
		padding: 20rpx 24rpx;
		border-top: 1rpx solid #f2f2f2;
		background-color: #fafafa;
	}

	.detail-btn {
		color: #409eff;
		font-size: 26rpx;
	}

	/* 适配小屏幕 */
	@media (max-width: 750rpx) {
		.info-grid .info-item {
			width: 100%;
		}

		.card-header {
			flex-direction: column;
			align-items: flex-start;
			gap: 16rpx;
		}

		.status-wrap {
			align-self: flex-start;
		}

		.list-container {
			height: calc(100vh - 420rpx);
		}
	}
</style>