<template>
  <div class="view-container local-view">
    <h1 class="view-title">本地音乐</h1>

    <!-- Toolbar -->
    <div class="toolbar">
      <button class="action-btn" @click="selectFolder" :disabled="scanning" v-if="supportsFolder">
        <Icon :icon="scanning ? 'lucide:loader-2' : 'lucide:folder-open'" width="18" height="18" />
        {{ scanning ? '扫描中...' : '选择文件夹' }}
      </button>
      <button class="action-btn" @click="selectFiles" :disabled="scanning">
        <Icon icon="lucide:file-plus" width="18" height="18" />
        选择文件
      </button>
      <button class="action-btn secondary" @click="clearAll" v-if="tracks.length > 0">
        <Icon icon="lucide:trash-2" width="18" height="18" />
        清空列表
      </button>
      <span class="track-count" v-if="tracks.length > 0">{{ tracks.length }} 首歌曲</span>
    </div>

    <!-- Progress -->
    <div class="progress-bar" v-if="scanProgress > 0 && scanProgress < 100">
      <div class="progress-fill" :style="{ width: scanProgress + '%' }"></div>
    </div>
    <p class="scan-status" v-if="scanMessage">{{ scanMessage }}</p>

    <!-- Song list -->
    <div class="track-list" v-if="tracks.length > 0">
      <div
        v-for="(track, idx) in tracks"
        :key="track.id"
        class="track-item"
        :class="{ active: currentTrackId === track.id }"
        @dblclick="playTrack(idx)"
      >
        <span class="track-idx">{{ idx + 1 }}</span>
        <div class="track-info">
          <span class="track-name">{{ track.name }}</span>
          <span class="track-artist">{{ track.artist }}</span>
        </div>
        <span class="track-duration">{{ formatDuration(track.duration) }}</span>
        <button class="play-btn" @click="playTrack(idx)" title="播放">
          <Icon icon="lucide:play" width="16" height="16" />
        </button>
      </div>
    </div>

    <!-- Empty state -->
    <div class="empty-state" v-else-if="!scanning">
      <div class="icon-box">
        <Icon icon="lucide:music" width="48" height="48" />
      </div>
      <p>{{ scanned ? '未找到音频文件' : '暂无本地音乐' }}</p>
      <p class="hint">选择包含音乐文件的文件夹或直接选择文件</p>
    </div>

    <!-- Hidden file input -->
    <input
      ref="fileInput"
      type="file"
      multiple
      accept="audio/*"
      style="display:none"
      @change="onFileSelected"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { Icon } from '@iconify/vue';
import { usePlayerStore } from '../stores/player';
import { scanFile, scanDirectory, loadTracks, saveTracks, clearSavedTracks, supportsDirectoryPicker, trackToSong, formatDuration } from '../utils/localMusic';
import type { ScannedTrack } from '../utils/localMusic';

const player = usePlayerStore();
const fileInput = ref<HTMLInputElement | null>(null);
const tracks = ref<ScannedTrack[]>([]);
const scanning = ref(false);
const scanProgress = ref(0);
const scanMessage = ref('');
const scanned = ref(false);
const supportsFolder = supportsDirectoryPicker();
const currentTrackId = ref('');

onMounted(async () => {
  const saved = await loadTracks();
  if (saved.length > 0) {
    tracks.value = saved as ScannedTrack[];
    scanned.value = true;
  }
});

async function selectFolder() {
  try {
    const dirHandle = await (window as any).showDirectoryPicker();
    scanning.value = true;
    scanProgress.value = 5;
    scanMessage.value = '正在扫描文件夹...';
    const found = await scanDirectory(dirHandle, (name) => {
      scanMessage.value = `扫描: ${name}`;
    });
    scanProgress.value = 90;
    scanMessage.value = `找到 ${found.length} 首歌曲`;
    if (found.length > 0) {
      tracks.value = found;
      await saveTracks(found);
      scanned.value = true;
    }
    scanProgress.value = 100;
    setTimeout(() => { scanProgress.value = 0; scanMessage.value = ''; }, 2000);
  } catch (err: any) {
    if (err?.name !== 'AbortError' && err?.name !== 'SecurityError') {
      console.warn('选择文件夹失败:', err);
    }
    scanMessage.value = '';
  } finally {
    scanning.value = false;
  }
}

function selectFiles() {
  fileInput.value?.click();
}

async function onFileSelected(e: Event) {
  const input = e.target as HTMLInputElement;
  if (!input.files || input.files.length === 0) return;
  scanning.value = true;
  scanProgress.value = 10;
  scanMessage.value = `处理 ${input.files.length} 个文件...`;
  const found: ScannedTrack[] = [];
  let done = 0;
  for (const file of Array.from(input.files)) {
    const track = await scanFile(file);
    if (track) found.push(track);
    done++;
    scanProgress.value = 10 + Math.round((done / input.files.length) * 80);
    scanMessage.value = `处理: ${file.name}`;
  }
  if (found.length > 0) {
    tracks.value = found;
    await saveTracks(found);
    scanned.value = true;
  }
  scanProgress.value = 100;
  setTimeout(() => { scanProgress.value = 0; scanMessage.value = ''; }, 1000);
  scanning.value = false;
  input.value = '';
}

function playTrack(idx: number) {
  const track = tracks.value[idx];
  if (!track) return;
  currentTrackId.value = track.id;
  const song = trackToSong(track);
  song.url = URL.createObjectURL(track.file);
  const list = tracks.value.map(t => {
    const s = trackToSong(t);
    s.url = URL.createObjectURL(t.file);
    return s;
  });
  player.playFromList(song, list);
}

async function clearAll() {
  tracks.value = [];
  scanned.value = false;
  await clearSavedTracks();
}
</script>

<style scoped>
.view-title {
  font-size: 2rem;
  font-weight: 700;
  margin-bottom: 24px;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.action-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 18px;
  border-radius: var(--radius-full);
  font-weight: 600;
  font-size: 0.9rem;
  border: none;
  cursor: pointer;
  background: var(--color-accent);
  color: var(--color-bg-primary);
  transition: opacity 0.2s;
}

.action-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.action-btn:hover:not(:disabled) {
  opacity: 0.85;
}

.action-btn.secondary {
  background: var(--color-bg-secondary);
  color: var(--color-text);
}

.track-count {
  margin-left: auto;
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

.progress-bar {
  height: 4px;
  background: var(--color-bg-secondary);
  border-radius: 2px;
  margin-bottom: 8px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 2px;
  transition: width 0.3s ease;
}

.scan-status {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  margin-bottom: 8px;
}

.track-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.track-item {
  display: flex;
  align-items: center;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  cursor: default;
  transition: background 0.15s;
  gap: 12px;
}

.track-item:hover {
  background: var(--color-bg-secondary);
}

.track-item.active {
  background: var(--color-bg-secondary);
  color: var(--color-accent);
}

.track-idx {
  width: 24px;
  text-align: right;
  color: var(--color-text-muted);
  font-size: 0.85rem;
  flex-shrink: 0;
}

.track-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.track-name {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.track-artist {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.track-duration {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  flex-shrink: 0;
}

.play-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  padding: 4px;
  border-radius: var(--radius-sm);
  transition: color 0.15s, background 0.15s;
  flex-shrink: 0;
}

.play-btn:hover {
  color: var(--color-accent);
  background: var(--color-bg-tertiary, rgba(128,128,128,0.1));
}

.empty-state {
  height: 400px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted);
}

.icon-box {
  background-color: var(--color-bg-secondary);
  padding: 24px;
  border-radius: 50%;
  margin-bottom: 24px;
}

.hint {
  font-size: 0.85rem;
  margin-top: 8px;
  opacity: 0.7;
}
</style>
