<template>
    <AppLayout>
        <div class="head">
            <div>
                <h1 class="title">洗车记录</h1>
                <p class="subtitle text-soft">共 {{ total }} 条记录{{ selectedCount ? ` · 已选 ${selectedCount} 条` : '' }}</p>
            </div>
            <div class="head-actions">
                <button
                    v-if="selectedCount > 0"
                    class="btn btn-danger"
                    @click="openBatchDelete"
                >批量删除 ({{ selectedCount }})</button>
                <router-link to="/washes/new" class="btn btn-primary">+ 新建</router-link>
            </div>
        </div>

        <div class="card filter">
            <button
                class="filter-toggle mobile-only"
                type="button"
                :aria-expanded="filterOpen"
                @click="filterOpen = !filterOpen"
            >
                <span>筛选</span>
                <span class="filter-count" v-if="activeFilterCount">{{ activeFilterCount }}</span>
                <span class="chevron" :class="{ on: filterOpen }">▾</span>
            </button>
            <div class="filter-body" :class="{ open: filterOpen }">
                <div class="filter-row">
                    <div>
                        <label class="label">类型</label>
                        <select v-model="filters.type" class="select" @change="reload">
                            <option value="">全部</option>
                            <option value="quick">快速</option>
                            <option value="full">标准</option>
                            <option value="detail">精洗</option>
                            <option value="other">其他</option>
                        </select>
                    </div>
                    <div>
                        <label class="label">车辆</label>
                        <select v-model="filters.vehicle_id" class="select" @change="reload">
                            <option value="">全部</option>
                            <option v-for="v in vehicles" :key="v.id" :value="v.id">{{ v.name }} ({{ v.plate }})</option>
                        </select>
                    </div>
                    <div>
                        <label class="label">开始</label>
                        <input v-model="filters.from" type="date" class="input" @change="reload" />
                    </div>
                    <div>
                        <label class="label">结束</label>
                        <input v-model="filters.to" type="date" class="input" @change="reload" />
                    </div>
                </div>
            </div>
        </div>

        <div class="card mt-4">
            <MobileCardList
                :columns="columns"
                :rows="rows"
                :is-selected="isSelected"
                :empty-text="'暂无记录'"
                row-key="id"
                @row-click="(row) => goTo(row.id)"
            >
                <template #checkbox="{ row }">
                    <input
                        type="checkbox"
                        :checked="isSelected(row.id)"
                        @change="toggleOne(row.id)"
                    />
                </template>
                <template #cell-date="{ row }">
                    {{ row.wash_date }}
                </template>
                <template #cell-type="{ row }">
                    <span class="pill" :class="typePill(row.wash_type)">{{ typeLabel(row.wash_type) }}</span>
                </template>
                <template #cell-vehicle="{ row }">
                    {{ row.vehicle_name || '—' }}
                </template>
                <template #cell-location="{ row }">
                    {{ row.location || '—' }}
                </template>
                <template #cell-cost="{ row }">
                    ¥ {{ Number(row.cost).toFixed(2) }}
                </template>
                <template #cell-duration="{ row }">
                    {{ row.duration_min ? row.duration_min + ' 分钟' : '—' }}
                </template>
                <template #cell-weather="{ row }">
                    {{ row.weather_desc || '—' }}
                </template>
                <template #actions="{ row }">
                    <button class="btn-link" @click.stop="openSingleDelete(row)">删除</button>
                    <span class="text-brand" style="font-size:12px">查看 →</span>
                </template>
                <template #empty>
                    暂无记录
                    <div class="mt-2"><router-link to="/washes/new" class="text-brand">+ 新建第一条</router-link></div>
                </template>
            </MobileCardList>
        </div>

        <!-- 批量删除确认 -->
        <ConfirmDangerDialog
            v-if="batchDialog.open"
            v-model="batchDialog.open"
            title="批量删除洗车记录"
            :message="`确认要删除 ${batchDialog.ids.length} 条洗车记录？`"
            mode="math"
            confirm-label="确认删除"
            :tips="['已删除记录可在「操作日志」中恢复']"
            :busy="batchDialog.busy"
            :error="batchDialog.error"
            @confirm="confirmBatchDelete"
            @cancel="batchDialog.open = false"
        />
        <!-- 单条删除确认 -->
        <ConfirmDangerDialog
            v-if="singleDialog.open"
            v-model="singleDialog.open"
            title="删除洗车记录"
            :message="`确认要删除这条记录${singleDialog.row ? '（' + singleDialog.row.wash_date + ' ¥' + Number(singleDialog.row.cost).toFixed(2) + '）' : ''}？`"
            mode="type"
            confirm-label="确认删除"
            :tips="['已删除记录可在「操作日志」中恢复']"
            :busy="singleDialog.busy"
            :error="singleDialog.error"
            @confirm="confirmSingleDelete"
            @cancel="singleDialog.open = false"
        />
    </AppLayout>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import AppLayout from '../components/AppLayout.vue';
import MobileCardList from '../components/MobileCardList.vue';
import ConfirmDangerDialog from '../components/ConfirmDangerDialog.vue';
import * as washesApi from '../api/washes';
import * as vehiclesApi from '../api/vehicles';
import { asArray } from '../api/client';

const router = useRouter();
const rows = ref([]);
const vehicles = ref([]);
const total = ref(0);
const filters = reactive({ type: '', vehicle_id: '', from: '', to: '' });
const selected = ref(new Set());
const filterOpen = ref(false);

const selectedCount = computed(() => selected.value.size);
const allSelected = computed(() => rows.value.length > 0 && selected.value.size === rows.value.length);
const someSelected = computed(() => selected.value.size > 0 && selected.value.size < rows.value.length);
const activeFilterCount = computed(() => {
    let n = 0;
    if (filters.type) n++;
    if (filters.vehicle_id) n++;
    if (filters.from) n++;
    if (filters.to) n++;
    return n;
});

// MobileCardList 列定义
const columns = [
    { key: 'date', label: '日期', primary: true, alwaysShow: true },
    { key: 'type', label: '类型', alwaysShow: true },
    { key: 'vehicle', label: '车辆', alwaysShow: true },
    { key: 'location', label: '位置' },
    { key: 'cost', label: '花费', alwaysShow: true },
    { key: 'duration', label: '耗时' },
    { key: 'weather', label: '天气' },
];

function isSelected(id) { return selected.value.has(id); }
function toggleOne(id) {
    const s = new Set(selected.value);
    s.has(id) ? s.delete(id) : s.add(id);
    selected.value = s;
}
function toggleAll() {
    if (allSelected.value) {
        selected.value = new Set();
    } else {
        selected.value = new Set(rows.value.map(r => r.id));
    }
}

const typeLabel = (t) => ({ quick: '快速', full: '标准', detail: '精洗', other: '其他' }[t] || t || '—');
const typePill = (t) => ({ quick: 'pill-blue', full: 'pill-green', detail: 'pill-warn' }[t] || 'pill-gray');
function goTo(id) { router.push({ name: 'wash-show', params: { id } }); }

// 单条删除
const singleDialog = reactive({ open: false, row: null, busy: false, error: '' });
function openSingleDelete(row) {
    singleDialog.row = row;
    singleDialog.busy = false;
    singleDialog.error = '';
    singleDialog.open = true;
}
async function confirmSingleDelete(challenge) {
    singleDialog.busy = true;
    singleDialog.error = '';
    try {
        await washesApi.remove(singleDialog.row.id);
        singleDialog.open = false;
        selected.value.delete(singleDialog.row.id);
        await reload();
    } catch (e) {
        singleDialog.error = e.response?.data?.error?.message || e.message;
    } finally {
        singleDialog.busy = false;
    }
}

// 批量删除
const batchDialog = reactive({ open: false, ids: [], busy: false, error: '' });
function openBatchDelete() {
    batchDialog.ids = [...selected.value];
    batchDialog.busy = false;
    batchDialog.error = '';
    batchDialog.open = true;
}
async function confirmBatchDelete(challenge) {
    batchDialog.busy = true;
    batchDialog.error = '';
    try {
        await washesApi.batchDelete(batchDialog.ids, challenge);
        batchDialog.open = false;
        selected.value = new Set();
        await reload();
    } catch (e) {
        singleDialog.error = '';
        batchDialog.error = e.response?.data?.error?.message || e.message;
        // 题目答错时换一道新题
        if (e.response?.data?.error?.code === 'CONFIRM_FAIL') {
            batchDialog.open = false;
            setTimeout(() => { batchDialog.open = true; }, 50);
        }
    } finally {
        batchDialog.busy = false;
    }
}

onMounted(async () => {
    try {
        const r = await vehiclesApi.list();
        vehicles.value = asArray(r.data, 'vehicles');
    } catch {}
    reload();
});
async function reload() {
    const params = { ...filters };
    if (!params.type) delete params.type;
    if (!params.vehicle_id) delete params.vehicle_id;
    if (!params.from) delete params.from;
    if (!params.to) delete params.to;
    const r = await washesApi.list(params);
    rows.value = r.data.rows || [];
    total.value = r.data.total || 0;
    // 清理已不存在的选中项
    const ids = new Set(rows.value.map(r => r.id));
    selected.value = new Set([...selected.value].filter(id => ids.has(id)));
}
</script>

<style scoped>
.head { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 20px; gap: 12px; flex-wrap: wrap; }
.head-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.title { font-size: 24px; font-weight: 600; margin: 0; letter-spacing: -0.02em; }
.subtitle { margin: 4px 0 0; font-size: 14px; }
.filter { padding: 16px 20px; }
.filter-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.check-col { width: 36px; padding-left: 16px; padding-right: 0; }
.row-link { cursor: pointer; }
.row-link.selected { background: rgba(232, 244, 249, 0.5); }
.row-actions { display: flex; align-items: center; gap: 12px; white-space: nowrap; }
.btn-link {
    background: none; border: 0; padding: 2px 4px; cursor: pointer;
    color: var(--danger); font-size: 13px;
}
.btn-link:hover { text-decoration: underline; }
.btn-danger { background: var(--danger); color: #fff; padding: 8px 16px; border-radius: var(--pill); border: 0; font-size: 14px; cursor: pointer; }
.btn-danger:hover { background: #d63c2f; }

/* === 移动端筛选折叠 === */
.filter-toggle {
    display: none;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    cursor: pointer;
    font-size: 15px;
    font-weight: 500;
    margin-bottom: 8px;
}
.filter-count {
    display: inline-flex;
    align-items: center; justify-content: center;
    min-width: 20px; height: 20px;
    padding: 0 6px;
    border-radius: var(--pill);
    background: var(--accent);
    color: #fff;
    font-size: 12px;
    margin-left: 6px;
}
.chevron {
    transition: transform .2s;
    color: var(--text-soft);
}
.chevron.on { transform: rotate(180deg); }

/* === 响应式 === */
@media (max-width: 900px) {
    .filter-row { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 767px) {
    .title { font-size: 20px; }
    .head { flex-direction: column; align-items: stretch; gap: 12px; }
    .head-actions { width: 100%; }
    .head-actions .btn { flex: 1; justify-content: center; }

    .filter { padding: 0; background: transparent; box-shadow: none; }
    .filter-toggle { display: flex; }
    .filter-body {
        display: none;
        background: var(--card);
        border-radius: var(--radius);
        padding: 16px;
        box-shadow: var(--card-shadow);
    }
    .filter-body.open { display: block; }
    .filter-row { grid-template-columns: 1fr; }
}

@media (max-width: 479px) {
    .head-actions .btn { padding: 8px 12px; font-size: 13px; }
    .head-actions .btn-danger { padding: 6px 10px; }
}
</style>
