<template>
	<view class="assign-order-page">
		<u-navbar :is-back="true" title="分配订单" :background="{'background':'#1479ff'}" title-color="#fff"
			:border-bottom="false">
		</u-navbar>
		<view class="b-border"></view>

		<scroll-view scroll-y class="main-scroll" @scrolltolower="loadMoreNurses">
			<!-- 当前订单信息 -->
			<view v-if="orderBrief.no" class="order-brief glass-card">
				<view class="order-brief__title">待分配订单</view>
				<view class="order-brief__row"><text class="label">订单号</text><text class="value">{{ orderBrief.no }}</text></view>
				<view class="order-brief__row" v-if="orderBrief.accompany_product && orderBrief.accompany_product.name">
					<text class="label">服务项目</text><text class="value">{{ orderBrief.accompany_product.name }}</text>
				</view>
				<view class="order-brief__row" v-if="orderBrief.time"><text class="label">服务时间</text><text class="value">{{ orderBrief.time }}</text></view>
				<view class="order-brief__row" v-if="orderBrief.user_archive && orderBrief.user_archive.name">
					<text class="label">被服务人</text><text class="value">{{ orderBrief.user_archive.name }}</text>
				</view>
			</view>
			<view v-else-if="orderLoadFailed" class="order-brief order-brief--empty glass-card">
				<text class="muted">未能加载订单信息，仍可分配（请核对订单号）</text>
			</view>

			<view class="nurse-panel">
				<view class="section-title">
					选择护工
					<text v-if="staffTotalHint" class="section-hint">共 {{ staffTotalHint }} 人</text>
				</view>
				<view class="search-box">
					<u-search v-model="searchKeyword" placeholder="搜索姓名或手机号"
						show-action shape="square" bg-color="#f0f2f5"
						@search="searchNurse" @clear="searchNurse" action-text="搜索" @custom="searchNurse" />
				</view>

				<view v-if="hasNurseList" class="nurse-items">
						<view
							v-for="nurse in nurseList"
							:key="nurse.id"
							:class="['nurse-item', { active: selectedNurseId === nurse.id }]"
							@click="selectNurseById(nurse.id)"
						>
							<view class="nurse-radio-wrap">
								<view class="nurse-radio" :class="{ on: selectedNurseId === nurse.id }">
									<view v-if="selectedNurseId === nurse.id" class="nurse-radio__dot"></view>
								</view>
							</view>
							<view class="nurse-avatar">
								<u-avatar :src="getNurseAvatar(nurse)" size="88"></u-avatar>
							</view>
							<view class="nurse-info">
								<view class="nurse-name-row">
									<text class="nurse-name">{{ nurse.name || '—' }}</text>
								</view>
								<view class="nurse-phone">{{ maskMobile(nurse.mobile) }}</view>
								<view v-if="nurseSexText(nurse)" class="nurse-sub">{{ nurseSexText(nurse) }}</view>
							</view>
						</view>
						<u-loadmore :margin-top="20" :margin-bottom="120" :status="loadStatus" />
				</view>
				<view v-else class="empty-state">
					<u-empty mode="list" text="暂无可指派护工，请更换关键词或不限制站点后重试" />
				</view>
			</view>
		</scroll-view>

		<!-- 底部操作 -->
		<view class="footer-bar safe-area">
			<u-button shape="circle" class="confirm-btn"
				:custom-style="confirmBtnStyle"
				:disabled="!selectedNurseId" @click="assignOrder">
				确认分配
			</u-button>
		</view>
	</view>
</template>

<script>
	import { ROOTPATH } from '@/common/config.js'

	export default {
		data() {
			return {
				orderId: '',
				nurseList: [],
				selectedNurseId: null,
				searchKeyword: '',
				loadStatus: 'loadmore',
				page: 1,
				pageSize: 10,
				loginRole: '',
				orderBrief: {},
				orderLoadFailed: false,
				staffTotal: 0,
			}
		},
		computed: {
			hasNurseList() {
				return this.nurseList.length > 0;
			},
			confirmBtnStyle() {
				const dis = !this.selectedNurseId;
				return {
					width: '100%',
					height: '88rpx',
					lineHeight: '88rpx',
					fontSize: '32rpx',
					color: '#fff',
					opacity: dis ? '0.55' : '1',
					background: dis ? '#c5ced9' : 'linear-gradient(to right, #476de4, #7bb9f7)',
					border: 'none'
				};
			},
			staffTotalHint() {
				if (this.loginRole !== 'staff' || !this.hasNurseList) return ''
				if (this.staffTotal > 0) return this.staffTotal
				return this.nurseList.length
			}
		},
		onLoad(options) {
			this.loginRole = uni.getStorageSync('login_role') || ''
			if (options.id) {
				this.orderId = options.id;
			}
			this.fetchOrderBrief();
			this.getNurseList();
		},
		methods: {
			/** 解压分页中的一条 nurses 数组 */
			extractPaginatedRows(payload) {
				if (!payload) return { rows: [], total: 0, last_page: 1 }
				let rows = []
				let total = 0
				let last_page = 1

				const tryArr = payload.data ?? payload.items ?? payload.list
				if (Array.isArray(tryArr)) {
					rows = tryArr
					total = payload.total ?? rows.length
					last_page = payload.last_page ?? 1
					return { rows, total, last_page }
				}
				if (Array.isArray(payload)) {
					return { rows: payload, total: payload.length, last_page: 1 }
				}
				return { rows: [], total: 0, last_page: 1 }
			},
			async fetchOrderBrief() {
				if (!this.orderId) return
				try {
					let detail = {}
					if (this.loginRole === 'staff') {
						detail = await this.$u.api.accompanyOrderDetail({ id: this.orderId })
					} else {
						detail = await this.$u.api.operatorOrderShow({
							id: this.orderId,
							'show_relation[0]': 'userArchive',
							'show_relation[1]': 'accompanyProduct',
							'show_relation[2]': 'hospital'
						})
					}
					const err = detail && (detail.errcode || detail.errCode)
					if (!err || err === 0) {
						this.orderBrief = (detail && detail.data != null ? detail.data : detail) || {}
					} else {
						this.orderLoadFailed = true
					}
				} catch (e) {
					console.error(e)
					this.orderLoadFailed = true
				}
			},
			async getNurseList(isLoadMore = false) {
				try {
					if (!isLoadMore) {
						this.page = 1;
						this.nurseList = [];
						this.selectedNurseId = null;
					}

					let res;

					if (this.loginRole === 'staff') {
						const params = {
							page: this.page,
							page_size: this.pageSize,
							sort_name: 'name',
							sort_type: 'asc'
						};
						const kw = (this.searchKeyword || '').trim();
						if (kw) params.keyword = kw;
						if (this.orderId) params.order_id = this.orderId;
						res = await this.$u.api.staffNursesForAssign(params);
					} else {
						const params = {
							page: this.page,
							page_size: this.pageSize,
							sort_name: 'name',
							sort_type: 'asc'
						};
						if (this.searchKeyword && this.searchKeyword.trim()) {
							const kw = this.searchKeyword.trim();
							params['filter[0][key]'] = 'name';
							params['filter[0][op]'] = 'like';
							params['filter[0][value]'] = kw;
						}
						params['filter[1][key]'] = 'status';
						params['filter[1][op]'] = 'eq';
						params['filter[1][value]'] = 1;
						res = await this.$u.api.nurseIndex(params);
					}

					const { rows, total, last_page } = this.extractPaginatedRows(res);

					if (rows.length === 0) {
						this.loadStatus = 'nomore';
						if (isLoadMore && this.page > 1) this.page--;
						if (!isLoadMore) this.nurseList = [];
						if (this.loginRole === 'staff') this.staffTotal = 0;
						return;
					}

					const dedupe = [];
					const seen = new Set();
					rows.forEach((n) => {
						const id = n && n.id;
						if (!id || seen.has(id)) return;
						seen.add(id);
						dedupe.push(n);
					});

					if (isLoadMore) this.nurseList.push(...dedupe);
					else this.nurseList = dedupe;

					if (this.loginRole === 'staff' && total != null && Number.isFinite(Number(total)) && Number(total) >= 0) {
						this.staffTotal = Number(total);
					}

					this.loadStatus =
						last_page !== undefined && last_page !== null
							? (this.page >= last_page ? 'nomore' : 'loadmore')
							: (rows.length >= this.pageSize ? 'loadmore' : 'nomore');
				} catch (error) {
					console.error('获取护工列表失败:', error);
					this.loadStatus = 'nomore';
					uni.showToast({
						title: '获取护工列表失败',
						icon: 'none'
					});
				}
			},

			searchNurse() {
				this.page = 1;
				this.getNurseList(false);
			},

			loadMoreNurses() {
				if (this.loadStatus !== 'loadmore') return;
				this.page++;
				this.getNurseList(true);
			},

			/** 仅用 id（原始类型），避免小程序端 key/事件编译生成非法 data-event-opts */
			selectNurseById(id) {
				if (id != null && id !== '') this.selectedNurseId = id;
			},

			maskMobile(m) {
				if (!m || m.length < 7) return m || '';
				const s = String(m);
				return s.slice(0, 3) + '****' + s.slice(-4);
			},

			nurseSexText(nurse) {
				if (!nurse) return '';
				const s = nurse.sex;
				if (s === 1 || s === '1' || s === '男') return '性别 · 男';
				if (s === 0 || s === '0' || s === '女') return '性别 · 女';
				if (typeof s === 'string' && s) return `性别 · ${s}`;
				return '';
			},

			async assignOrder() {
				if (!this.selectedNurseId) {
					uni.showToast({ title: '请选择护工', icon: 'none' });
					return;
				}

				try {
					const res =
						this.loginRole === 'staff'
							? await this.$u.api.staffOrderSave({
									id: this.orderId,
									nurse_id: this.selectedNurseId
								})
							: await this.$u.api.operatorOrderSave({
									id: this.orderId,
									nurse_id: this.selectedNurseId
								});

					const err = res.errcode ?? res.errCode ?? res.errorCode;
					if (err && err !== 0) {
						uni.showToast({ title: res.errmsg || res.message || '分配失败', icon: 'none' });
						return;
					}

					uni.showToast({ title: '分配成功', icon: 'success' });
					setTimeout(() => uni.navigateBack(), 1500);
				} catch (error) {
					console.error('分配订单失败:', error);
					uni.showToast({
						title: '分配失败',
						icon: 'none'
					});
				}
			},

			getNurseAvatar(nurse) {
				const wrap = nurse.avatar_detail || nurse.avatarDetail;
				let raw = '';
				if (wrap) {
					if (typeof wrap === 'object' && wrap.url) raw = wrap.url;
				}
				if (!raw && typeof nurse.avatar === 'string' && /^https?:\/\//.test(nurse.avatar)) {
					raw = nurse.avatar;
				}
				if (!raw) return '/static/default-avatar.png'
				if (/^https?:\/\//i.test(raw)) return raw;
				const base = ROOTPATH.replace(/\/$/, '');
				return raw.startsWith('/') ? `${base}${raw}` : `${base}/${raw}`;
			}
		}
	}
</script>

<style scoped lang="scss">
	.assign-order-page {
		min-height: 100vh;
		height: 100vh;
		background: #f6f8fb;
		display: flex;
		flex-direction: column;
	}

	.main-scroll {
		flex: 1;
		height: 0;
		overflow: hidden;
	}

	.b-border {
		flex-shrink: 0;
		width: 100%;
		height: 30rpx;
		border-radius: 0 0 120rpx 120rpx;
		background-color: #1479ff;
	}

	.glass-card {
		background: #fff;
		border-radius: 20rpx;
		box-shadow: 0 6rpx 24rpx rgba(20, 121, 255, 0.08);
	}

	.order-brief {
		margin: 24rpx 24rpx 0;
		padding: 28rpx 30rpx;

		&--empty {
			padding: 24rpx 30rpx;
			.muted {
				font-size: 26rpx;
				color: #999;
				line-height: 1.5;
			}
		}

		&__title {
			font-size: 28rpx;
			font-weight: 600;
			color: #1479ff;
			margin-bottom: 20rpx;
		}

		&__row {
			display: flex;
			justify-content: space-between;
			align-items: flex-start;
			font-size: 28rpx;
			padding: 12rpx 0;
			border-bottom: 1rpx solid #f0f0f0;

			&:last-child {
				border-bottom: none;
				padding-bottom: 0;
			}

			.label {
				color: #888;
				flex-shrink: 0;
				width: 160rpx;
			}

			.value {
				color: #333;
				text-align: right;
				flex: 1;
				word-break: break-all;
			}
		}
	}

	.nurse-panel {
		margin: 24rpx;
		padding-bottom: 24rpx;
	}

	.section-title {
		font-size: 32rpx;
		font-weight: bold;
		color: #333;
		margin-bottom: 20rpx;
		display: flex;
		align-items: baseline;
		gap: 16rpx;
	}

	.section-hint {
		font-size: 24rpx;
		font-weight: normal;
		color: #999;
	}

	.search-box {
		margin-bottom: 24rpx;
	}

	.nurse-items {
		background: #fff;
		border-radius: 20rpx;
		overflow: hidden;
		box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
	}

	.nurse-item {
		display: flex;
		align-items: center;
		padding: 28rpx 24rpx 28rpx 20rpx;
		border-bottom: 1rpx solid #f0f2f5;

		&:last-of-type {
			border-bottom: none;
		}

		&.active {
			background: linear-gradient(90deg, #f2f8ff 0%, #fff 56%);
			box-shadow: inset 4rpx 0 0 #1479ff;
		}
	}

	.nurse-radio-wrap {
		width: 44rpx;
		display: flex;
		justify-content: center;
		margin-right: 8rpx;
		flex-shrink: 0;
	}

	.nurse-radio {
		width: 36rpx;
		height: 36rpx;
		border-radius: 50%;
		border: 2rpx solid #c8ccd4;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-shrink: 0;

		&.on {
			border-color: #1479ff;
			background: #e8f1ff;
		}

		&__dot {
			width: 18rpx;
			height: 18rpx;
			border-radius: 50%;
			background: #1479ff;
		}
	}

	.nurse-avatar {
		margin-right: 22rpx;
		flex-shrink: 0;
	}

	.nurse-info {
		flex: 1;
		min-width: 0;
	}

	.nurse-name-row {
		display: flex;
		align-items: center;
		gap: 12rpx;
		flex-wrap: wrap;
		margin-bottom: 10rpx;
	}

	.nurse-name {
		font-size: 28rpx;
		color: #666;
		letter-spacing: 1rpx;
		font-family: system-ui;
		margin-bottom: 6rpx;
	}

	.nurse-sub {
		font-size: 22rpx;
		color: #999;
		line-height: 1.4;
	}

	.empty-state {
		background: #fff;
		border-radius: 20rpx;
		padding: 80rpx 20rpx 120rpx;
		box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.03);
	}

	.footer-bar {
		flex-shrink: 0;
		padding: 20rpx 30rpx 40rpx;
		background: #fff;
		box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.06);
	}

	.confirm-btn {
		opacity: 1 !important;
		border: none !important;
		position: relative;
		z-index: 2;

		&::after {
			border: none;
		}
	}

	.safe-area {
		padding-bottom: calc(40rpx + constant(safe-area-inset-bottom));
		padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
	}
</style>
