<template>
    <!-- 根节点：section 分组展示 -->
    <template v-if="depth === 0">
        <div class="group">
            <div class="group__header">
                <div class="group__accent" />
                <div class="group__name">
                    <el-icon class="group__name-icon"><FolderOpened /></el-icon>
                    {{ node.dept_name }}
                </div>
                <div class="group__amount-wrap">
                    <el-input-number
                        v-model="node.target_amount"
                        :min="0"
                        :precision="2"
                        :step="1000"
                        controls-position="right"
                        placeholder="0.00"
                        class="group__amount-input"
                    />
                </div>
                <div class="group__remark-wrap">
                    <el-input
                        v-model="node.remark"
                        maxlength="255"
                        placeholder="备注（选填）"
                        clearable
                    />
                </div>
                <div class="group__badge-wrap">
                    <el-tag v-if="node.target_id" size="small" type="success" effect="plain" round>已保存</el-tag>
                    <span v-else class="group__unsaved-dot" />
                </div>
            </div>

            <div v-if="node.children?.length" class="group__body">
                <MubiaoDeptNode
                    v-for="c in node.children"
                    :key="c.dept_id"
                    :node="c"
                    :depth="1"
                />
            </div>
        </div>
    </template>

    <!-- 子节点：表格行 -->
    <template v-else>
        <div class="row" :data-depth="String(Math.min(depth, 4))">
            <div class="row__indent" :style="{ width: `${(depth - 1) * 20 + 16}px` }">
                <div class="row__connector" />
            </div>

            <div class="row__dept">
                <div class="row__dot" />
                <div class="row__dept-text">
                    <span class="row__name">{{ node.dept_name }}</span>
                    <span v-if="parentPath" class="row__path">{{ parentPath }}</span>
                </div>
                <el-tag v-if="node.target_id" size="small" type="success" effect="plain" round class="row__saved">已保存</el-tag>
            </div>

            <div class="row__amount">
                <el-input-number
                    v-model="node.target_amount"
                    :min="0"
                    :precision="2"
                    :step="1000"
                    controls-position="right"
                    placeholder="0.00"
                    class="row__amount-input"
                />
            </div>

            <div class="row__remark">
                <el-input
                    v-model="node.remark"
                    maxlength="255"
                    placeholder="备注（选填）"
                    clearable
                />
            </div>
        </div>

        <MubiaoDeptNode
            v-for="c in node.children"
            :key="c.dept_id"
            :node="c"
            :depth="depth + 1"
        />
    </template>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { FolderOpened } from '@element-plus/icons-vue'

defineOptions({ name: 'MubiaoDeptNode' })

export interface DeptTargetRow {
    dept_id: number
    dept_name: string
    dept_path: string
    target_id: number
    target_amount: number
    remark: string
    children?: DeptTargetRow[]
}

const props = defineProps<{
    node: DeptTargetRow
    depth: number
}>()

const segments = computed(() =>
    props.node.dept_path.split(/\s*\/\s*/).filter(Boolean)
)

const parentPath = computed(() =>
    segments.value.slice(0, -1).join(' › ')
)
</script>

<style lang="scss" scoped>
/* ── 根节点：分组区块 ── */
.group {
    border-bottom: 1px solid var(--el-border-color-lighter);

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

.group__header {
    display: flex;
    align-items: center;
    gap: 0;
    min-height: 54px;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--el-color-primary) 6%, var(--el-bg-color)) 0%,
        color-mix(in srgb, var(--el-color-primary) 2%, var(--el-bg-color)) 50%,
        var(--el-bg-color) 100%
    );
    border-bottom: 1px solid color-mix(in srgb, var(--el-color-primary) 12%, var(--el-border-color-lighter));
    padding-right: 16px;
    cursor: default;
    transition: background 0.18s ease;

    &:hover {
        background: linear-gradient(90deg,
            color-mix(in srgb, var(--el-color-primary) 10%, var(--el-bg-color)) 0%,
            color-mix(in srgb, var(--el-color-primary) 4%, var(--el-bg-color)) 50%,
            var(--el-fill-color-extra-light) 100%
        );
    }
}

.group__accent {
    flex-shrink: 0;
    width: 4px;
    align-self: stretch;
    background: linear-gradient(180deg, var(--el-color-primary), var(--el-color-primary-light-3));
    border-radius: 0 2px 2px 0;
    margin-right: 12px;
}

.group__name {
    flex: 0 0 auto;
    width: 220px;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--el-color-primary-dark-2);
    padding-right: 12px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: flex;
    align-items: center;
    gap: 6px;
}

.group__name-icon {
    font-size: 15px;
    opacity: 0.7;
    flex-shrink: 0;
}

.group__amount-wrap {
    flex: 0 0 194px;
    border-left: 1px solid color-mix(in srgb, var(--el-color-primary) 15%, var(--el-border-color-lighter));
    padding: 9px 12px;
}

.group__amount-input {
    width: 170px;

    :deep(.el-input__wrapper) {
        border-radius: 7px;
        background: var(--el-bg-color);
        box-shadow: 0 0 0 1.5px var(--el-color-primary-light-5) inset,
                    0 1px 3px rgba(0, 0, 0, 0.06);
        transition: box-shadow 0.15s;

        &:hover {
            box-shadow: 0 0 0 1.5px var(--el-color-primary-light-3) inset,
                        0 2px 6px rgba(0, 0, 0, 0.08);
        }

        &.is-focus {
            box-shadow: 0 0 0 2px var(--el-color-primary-light-3) inset !important;
        }
    }
}

.group__remark-wrap {
    flex: 1;
    border-left: 1px solid color-mix(in srgb, var(--el-color-primary) 15%, var(--el-border-color-lighter));
    padding: 9px 12px;
}

.group__badge-wrap {
    flex: 0 0 60px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.group__unsaved-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--el-border-color);
    display: block;
}

.group__body {
    background: var(--el-bg-color);
}

/* ── 子节点：表格行 ── */
.row {
    display: flex;
    align-items: center;
    min-height: 46px;
    border-bottom: 1px solid var(--el-border-color-lighter);
    transition: background 0.12s ease;
    padding-right: 16px;
    cursor: default;

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

    &:hover {
        background: var(--el-fill-color-extra-light);

        .row__dot {
            transform: scale(1.3);
        }
    }

    /* 深度色阶 */
    &[data-depth='1'] {
        --dot: #67c23a;
        --connector: color-mix(in srgb, #67c23a 30%, var(--el-border-color));
    }
    &[data-depth='2'] {
        --dot: #e6a23c;
        --connector: color-mix(in srgb, #e6a23c 30%, var(--el-border-color));
    }
    &[data-depth='3'] {
        --dot: #909399;
        --connector: var(--el-border-color);
    }
    &[data-depth='4'] {
        --dot: var(--el-border-color-darker);
        --connector: var(--el-border-color-light);
    }
}

.row__indent {
    flex-shrink: 0;
    position: relative;
    align-self: stretch;
    min-width: 16px;
}

.row__connector {
    position: absolute;
    left: calc(100% - 2px);
    top: 0;
    bottom: 50%;
    width: 10px;
    border-left: 1.5px dashed var(--connector, var(--el-border-color));
    border-bottom: 1.5px dashed var(--connector, var(--el-border-color));
    border-radius: 0 0 0 4px;
}

.row__dept {
    flex: 0 0 auto;
    width: 220px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px 8px 8px;
}

.row__dot {
    flex-shrink: 0;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--dot, #909399);
    transition: transform 0.15s ease;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--dot, #909399) 20%, transparent);
}

.row__dept-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.row__name {
    font-size: 13px;
    font-weight: 600;
    color: var(--el-text-color-primary);
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.row__path {
    font-size: 11px;
    color: var(--el-text-color-placeholder);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.row__saved {
    flex-shrink: 0;
}

.row__amount {
    flex: 0 0 194px;
    border-left: 1px solid var(--el-border-color-lighter);
    border-right: 1px solid var(--el-border-color-lighter);
    padding: 8px 12px;
}

.row__amount-input {
    width: 170px;

    :deep(.el-input__wrapper) {
        border-radius: 7px;
        transition: box-shadow 0.15s;

        &:hover {
            box-shadow: 0 0 0 1px var(--el-color-primary-light-5) inset;
        }
    }
}

.row__remark {
    flex: 1;
    padding: 8px 0 8px 12px;
}

@media (max-width: 900px) {
    .group__header,
    .row {
        flex-wrap: wrap;
        padding-bottom: 10px;
    }
    .group__name,
    .row__dept { width: 100%; }
    .group__amount-wrap,
    .row__amount { border: none; flex: 0 0 auto; }
    .group__remark-wrap,
    .row__remark { flex: 1 1 180px; border: none; }
    .group__amount-input,
    .row__amount-input { width: 160px; }
}
</style>
