<template>
    <view>
        <u-form-item :label="label" :prop="inputProp" :required="required" :labelWidth="labelWidth">
            <view class="selector-trigger" @tap.stop="openPicker" @click.stop="openPicker">
                <u-input class="selector-input" :value="currentValue" :placeholder="displayPlaceholder" :readonly="readonly" :disabled="disabled"
                    @focus="openPicker" @click="openPicker" @tap="openPicker"></u-input>
            </view>
        </u-form-item>

        <view class="selector-mask" :class="{ show: visible }" @tap="closePicker"></view>
        <view class="selector-panel" :class="{ show: visible }">
            <view class="selector-header">
                <view class="selector-action" @tap="closePicker">取消</view>
                <view class="selector-title">{{ displayTitle }}</view>
                <view v-if="showAddGoods" class="selector-action selector-action-wide" @tap.stop="openAddGoods">新增商品</view>
                <view v-else class="selector-action selector-action-placeholder">取消</view>
            </view>
            <view class="selector-search">
                <u-search :show-action="false" v-model="keyword" :placeholder="displaySearchPlaceholder"></u-search>
            </view>
            <scroll-view :scroll-y="true" class="selector-list">
                <view v-if="loading" class="selector-state">加载中...</view>
                <view v-else-if="filteredList.length === 0" class="selector-state">{{ emptyText }}</view>
                <view v-else class="selector-list-inner">
                    <view class="selector-card" v-for="item in filteredList" :key="item.id || item.tradeName"
                        @tap="selectItem(item)">
                        <view class="selector-name">{{ item.tradeName || '-' }}</view>
                        <view class="selector-meta" v-if="showStock">
                            <text>库存：{{ displayStock(item) }}</text>
                            <text v-if="item.company">单位：{{ item.company }}</text>
                        </view>
                        <view class="selector-meta" v-if="item.brand || item.specification || (!showStock && item.company)">
                            <text v-if="item.brand">品牌：{{ item.brand }}</text>
                            <text v-if="item.specification">规格：{{ item.specification }}</text>
                            <text v-if="!showStock && item.company">单位：{{ item.company }}</text>
                        </view>
                    </view>
                </view>
            </scroll-view>
        </view>

        <view class="add-mask" :class="{ show: addVisible }" @tap="closeAddGoods"></view>
        <view class="add-panel" :class="{ show: addVisible }">
            <view class="selector-header">
                <view class="selector-action" @tap="closeAddGoods">取消</view>
                <view class="selector-title">新增商品</view>
                <view class="selector-action" @tap.stop="submitAddGoods">{{ addLoading ? '保存中' : '保存' }}</view>
            </view>
            <scroll-view :scroll-y="true" class="add-body">
                <u-form-item label="所属分类" :required="true" labelWidth="76px">
                    <view class="selector-trigger" @tap.stop="toggleCategoryList" @click.stop="toggleCategoryList">
                        <u-input class="selector-input" :value="addForm.parentName" placeholder="请选择所属分类"
                            readonly :disabled="isAddParentLocked"></u-input>
                    </view>
                </u-form-item>
                <u-form-item label="名称" :required="true" labelWidth="76px">
                    <u-input v-model="addForm.name" placeholder="请填写商品名称"></u-input>
                </u-form-item>
                <u-form-item label="品牌" labelWidth="76px">
                    <u-input v-model="addForm.brand" placeholder="请填写品牌"></u-input>
                </u-form-item>
                <u-form-item label="规格" labelWidth="76px">
                    <u-input v-model="addForm.specification" placeholder="请填写规格"></u-input>
                </u-form-item>
                <u-form-item label="单位" labelWidth="76px">
                    <u-input v-model="addForm.company" placeholder="请填写单位"></u-input>
                </u-form-item>
            </scroll-view>
        </view>

        <view class="category-mask" :class="{ show: categoryListVisible }" @tap="closeCategoryList"></view>
        <view class="category-panel" :class="{ show: categoryListVisible }">
            <view class="selector-header">
                <view class="selector-action" @tap="closeCategoryList">取消</view>
                <view class="selector-title">选择分类</view>
                <view class="selector-action selector-action-placeholder">取消</view>
            </view>
            <view class="selector-search">
                <u-search :show-action="false" v-model="categoryKeyword" placeholder="搜索分类"></u-search>
            </view>
            <scroll-view :scroll-y="true" class="category-list">
                <view v-if="categoryOptions.length === 0" class="selector-state category-state">暂无可选分类</view>
                <view v-for="item in categoryOptions" :key="item.id" class="category-item"
                    @tap="selectCategory(item)">
                    {{ item.name || '-' }}
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script>
import MaterialTypeService from '@/api/psi/MaterialTypeService'

export default {
    name: 'PsiGoodsSelector',
    props: {
        rowIndex: Number,
        indexExperience: Number,
        inputForm: {
            type: Object,
            default: () => ({})
        },
        rowPath: {
            type: String,
            default: 'detailInfos'
        },
        valueFields: {
            type: Array,
            default: () => ['tradeName']
        },
        propField: {
            type: String,
            default: ''
        },
        label: {
            type: String,
            default: '物品名称'
        },
        labelWidth: {
            type: String,
            default: '68px'
        },
        placeholder: {
            type: String,
            default: ''
        },
        title: {
            type: String,
            default: ''
        },
        searchPlaceholder: {
            type: String,
            default: ''
        },
        emptyText: {
            type: String,
            default: '暂无可选物品'
        },
        parentIdField: {
            type: String,
            default: ''
        },
        parentNameField: {
            type: String,
            default: ''
        },
        parentRequiredText: {
            type: String,
            default: '请先选择分类'
        },
        requireParent: {
            type: Boolean,
            default: false
        },
        showStock: {
            type: Boolean,
            default: true
        },
        showAddGoods: {
            type: Boolean,
            default: false
        },
        required: {
            type: Boolean,
            default: true
        },
        readonly: {
            type: Boolean,
            default: true
        },
        disabled: Boolean
    },
    data() {
        return {
            visible: false,
            loading: false,
            addVisible: false,
            addLoading: false,
            categoryListVisible: false,
            keyword: '',
            categoryKeyword: '',
            rawMaterialList: [],
            goodsList: [],
            addForm: this.createAddForm(),
            materialTypeService: null
        }
    },
    computed: {
        actualIndex() {
            if (this.rowIndex !== undefined && this.rowIndex !== null) {
                return this.rowIndex
            }
            return this.indexExperience
        },
        rows() {
            return this.inputForm[this.rowPath] || []
        },
        currentRow() {
            return this.rows[this.actualIndex] || {}
        },
        inputProp() {
            const field = this.propField || this.valueFields[0] || ''
            return field ? `${this.rowPath}[${this.actualIndex}].${field}` : ''
        },
        currentValue() {
            for (let i = 0; i < this.valueFields.length; i++) {
                const value = this.currentRow[this.valueFields[i]]
                if (!this.isEmpty(value)) {
                    return value
                }
            }
            return ''
        },
        parentId() {
            return this.parentIdField ? this.currentRow[this.parentIdField] : ''
        },
        currentParentName() {
            if (this.parentNameField && !this.isEmpty(this.currentRow[this.parentNameField])) {
                return this.currentRow[this.parentNameField]
            }
            return this.currentRow.procurementType || this.currentRow.typeName || this.currentRow.categoryName || ''
        },
        isAddParentLocked() {
            return !!this.parentIdField && !this.isEmpty(this.parentId)
        },
        displayPlaceholder() {
            return this.placeholder || `请选择${this.label}`
        },
        displayTitle() {
            return this.title || `选择${this.label}`
        },
        displaySearchPlaceholder() {
            return this.searchPlaceholder || `搜索${this.label}`
        },
        filteredList() {
            const keyword = (this.keyword || '').trim().toLowerCase()
            if (!keyword) {
                return this.goodsList
            }
            return this.goodsList.filter(item => (item.tradeName || '').toLowerCase().includes(keyword))
        },
        categoryOptions() {
            const keyword = (this.categoryKeyword || '').trim().toLowerCase()
            return this.flattenNodes(this.rawMaterialList).filter(item => {
                const isGoods = String(item.infoType || item.info_type || '') === '1'
                const name = item.name || item.tradeName || ''
                return !isGoods && (!keyword || name.toLowerCase().includes(keyword))
            }).map(item => ({
                ...item,
                name: item.name || item.tradeName || ''
            }))
        }
    },
    created() {
        this.materialTypeService = new MaterialTypeService()
    },
    methods: {
        createAddForm() {
            return {
                businessType: '',
                infoType: '1',
                name: '',
                brand: '',
                specification: '',
                company: '',
                parentId: '',
                parentName: ''
            }
        },
        isEmpty(value) {
            if (value === null || value === undefined) {
                return true
            }
            if (typeof value === 'string' && value.trim() === '') {
                return true
            }
            if (Array.isArray(value) && value.length === 0) {
                return true
            }
            return false
        },
        displayStock(item) {
            if (!this.isEmpty(item.currentInventory)) {
                return item.currentInventory
            }
            if (!this.isEmpty(item.surplusNumber)) {
                return item.surplusNumber
            }
            return '0'
        },
        async openPicker() {
            if (this.disabled) {
                return
            }
            if (this.visible) {
                return
            }
            if (this.requireParent && this.isEmpty(this.parentId)) {
                uni.showToast({
                    title: this.parentRequiredText,
                    icon: 'none'
                })
                return
            }
            this.visible = true
            this.keyword = ''
            await this.loadGoodsList()
        },
        closePicker() {
            this.visible = false
            this.closeAddGoods()
        },
        async loadGoodsList() {
            this.loading = true
            try {
                const data = await this.materialTypeService.cgList()
                this.rawMaterialList = data || []
                this.goodsList = this.flattenNodes(this.rawMaterialList).filter(item => {
                    const itemParentId = item.parentId || item.parent_id || ''
                    const isGoods = String(item.infoType || item.info_type || '') === '1'
                    const matchParent = !this.parentIdField || this.isEmpty(this.parentId) ||
                        String(itemParentId) === String(this.parentId)
                    return isGoods && matchParent
                }).map(item => ({
                    ...item,
                    tradeName: item.tradeName || item.name || ''
                }))
            } catch (e) {
                this.goodsList = []
                uni.showToast({
                    title: `${this.label}数据加载失败`,
                    icon: 'none'
                })
            } finally {
                this.loading = false
            }
        },
        flattenNodes(nodes, result = []) {
            ;(nodes || []).forEach(node => {
                result.push(node)
                if (node.children && node.children.length) {
                    this.flattenNodes(node.children, result)
                }
            })
            return result
        },
        selectItem(item) {
            this.$emit('selected', {
                index: this.actualIndex,
                item
            })
            this.closePicker()
        },
        async openAddGoods() {
            if (this.addLoading) {
                return
            }
            this.addForm = this.createAddForm()
            if (this.isAddParentLocked) {
                this.addForm.parentId = this.parentId
                this.addForm.parentName = this.currentParentName
            }
            this.categoryKeyword = ''
            this.categoryListVisible = false
            this.addVisible = true
            if (this.rawMaterialList.length === 0) {
                await this.loadMaterialListForAdd()
            }
        },
        closeAddGoods() {
            if (this.addLoading) {
                return
            }
            this.addVisible = false
            this.categoryListVisible = false
        },
        async loadMaterialListForAdd() {
            try {
                const data = await this.materialTypeService.cgList()
                this.rawMaterialList = data || []
            } catch (e) {
                this.rawMaterialList = []
                uni.showToast({
                    title: '分类数据加载失败',
                    icon: 'none'
                })
            }
        },
        toggleCategoryList() {
            if (this.isAddParentLocked) {
                return
            }
            this.categoryListVisible = !this.categoryListVisible
        },
        closeCategoryList() {
            this.categoryListVisible = false
        },
        selectCategory(item) {
            this.addForm.parentId = item.id
            this.addForm.parentName = item.name || item.tradeName || ''
            this.categoryListVisible = false
        },
        async submitAddGoods() {
            if (this.addLoading) {
                return
            }
            if (this.isEmpty(this.addForm.parentId)) {
                uni.showToast({
                    title: '请选择所属分类',
                    icon: 'none'
                })
                return
            }
            if (this.isEmpty(this.addForm.name)) {
                uni.showToast({
                    title: '请填写商品名称',
                    icon: 'none'
                })
                return
            }
            const submitData = {
                ...this.addForm,
                infoType: '1'
            }
            delete submitData.parentName
            this.addLoading = true
            try {
                const data = await this.materialTypeService.save(submitData)
                const result = this.getResponseData(data)
                if (typeof result === 'string' && result.indexOf('不能新增') > -1) {
                    uni.showToast({
                        title: result,
                        icon: 'none'
                    })
                    return
                }
                uni.showToast({
                    title: '保存成功',
                    icon: 'success'
                })
                this.addVisible = false
                await this.loadGoodsList()
            } catch (e) {
                uni.showToast({
                    title: '商品保存失败',
                    icon: 'none'
                })
            } finally {
                this.addLoading = false
            }
        },
        getResponseData(data) {
            if (data && Object.prototype.hasOwnProperty.call(data, 'data')) {
                return data.data
            }
            return data
        }
    }
}
</script>

<style scoped>
.selector-mask {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    opacity: 0;
    visibility: hidden;
    transition: all 0.25s ease;
    z-index: 1000;
}

.selector-trigger {
    width: 100%;
}

.selector-input {
    pointer-events: none;
}

.selector-mask.show {
    opacity: 1;
    visibility: visible;
}

.add-mask {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    opacity: 0;
    visibility: hidden;
    transition: all 0.25s ease;
    z-index: 1002;
}

.add-mask.show {
    opacity: 1;
    visibility: visible;
}

.selector-panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 68vh;
    background: #f7f9fc;
    border-radius: 28rpx 28rpx 0 0;
    transform: translateY(100%);
    transition: transform 0.25s ease;
    z-index: 1001;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.selector-panel.show {
    transform: translateY(0);
}

.add-panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 78vh;
    background: #fff;
    border-radius: 28rpx 28rpx 0 0;
    transform: translateY(100%);
    transition: transform 0.25s ease;
    z-index: 1003;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.add-panel.show {
    transform: translateY(0);
}

.add-body {
    flex: 1;
    height: 0;
    padding: 18rpx 28rpx 40rpx;
    box-sizing: border-box;
}

.category-mask {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    opacity: 0;
    visibility: hidden;
    transition: all 0.25s ease;
    z-index: 1004;
}

.category-mask.show {
    opacity: 1;
    visibility: visible;
}

.category-panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 62vh;
    background: #f7f9fc;
    border-radius: 28rpx 28rpx 0 0;
    transform: translateY(100%);
    transition: transform 0.25s ease;
    z-index: 1005;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.category-panel.show {
    transform: translateY(0);
}

.category-list {
    flex: 1;
    height: 0;
    padding: 16rpx 24rpx 32rpx;
    box-sizing: border-box;
}

.category-item {
    margin-bottom: 14rpx;
    padding: 22rpx 24rpx;
    background: #fff;
    border-radius: 16rpx;
    font-size: 28rpx;
    color: #1f2937;
    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
}

.category-state {
    padding-top: 120rpx;
}

.selector-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 28rpx 32rpx 16rpx;
    background: #fff;
    border-bottom: 1rpx solid #eef2f7;
}

.selector-title {
    font-size: 32rpx;
    font-weight: 600;
    color: #1f2937;
}

.selector-action {
    min-width: 80rpx;
    font-size: 28rpx;
    color: #2979ff;
}

.selector-action-wide {
    min-width: 128rpx;
    text-align: right;
}

.selector-action-placeholder {
    opacity: 0;
}

.selector-search {
    padding: 20rpx 24rpx 8rpx;
    background: #fff;
}

.selector-list {
    flex: 1;
    height: 0;
    padding: 16rpx 24rpx 32rpx;
    box-sizing: border-box;
}

.selector-list-inner {
    display: flex;
    flex-direction: column;
    gap: 16rpx;
}

.selector-state {
    padding-top: 120rpx;
    text-align: center;
    font-size: 28rpx;
    color: #94a3b8;
}

.selector-card {
    background: #fff;
    border-radius: 20rpx;
    padding: 24rpx;
    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
}

.selector-name {
    font-size: 30rpx;
    font-weight: 600;
    color: #0f172a;
}

.selector-meta {
    display: flex;
    gap: 16rpx;
    margin-top: 10rpx;
    font-size: 24rpx;
    color: #64748b;
    flex-wrap: wrap;
}
</style>
