<script setup>
import { mediaService } from '@/api/mediaService';
import { postService } from '@/api/postService';
import { formatDate, formatDuration } from "@/utils/date";
import { formatFileSize } from "@/utils/filesize";
import { getFileIcon, getFileTypeByMimeCN } from "@/utils/filetype";
import { useToast } from 'primevue/usetoast';
import { computed, onMounted, reactive, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';

// PrimeVue components
import Badge from 'primevue/badge';
import Button from 'primevue/button';
import Column from 'primevue/column';
import DataTable from 'primevue/datatable';
import Dialog from 'primevue/dialog';
import InputNumber from 'primevue/inputnumber';
import InputText from 'primevue/inputtext';
import ProgressSpinner from 'primevue/progressspinner';
import RadioButton from 'primevue/radiobutton';
import Textarea from 'primevue/textarea';
import Toast from 'primevue/toast';

import {
    BsFileEarmark,
    BsFileExcel,
    BsFileImage,
    BsFileMusic,
    BsFilePdf,
    BsFilePlayFill,
    BsFilePpt,
    BsFileText,
    BsFileWord,
    BsFileZip
} from 'vue-icons-plus/bs';

// Create icons object
const icons = {
    BsFileEarmark,
    BsFileExcel,
    BsFileImage,
    BsFileMusic,
    BsFilePdf,
    BsFilePlayFill,
    BsFilePpt,
    BsFileText,
    BsFileWord,
    BsFileZip
};


const router = useRouter();
const route = useRoute();
const toast = useToast();
const loading = ref(true);


// Form state
const post = reactive({
    id: null,
    title: '',
    price: 0,
    discount: 100,
    introduction: '',
    selectedMedia: [],
    medias: [],
    status: 0,
    head_images: [], // Add head images array
});

// Status options
const statusOptions = [
    { label: '发布', value: 1 },
    { label: '草稿', value: 0 }
];

// Validation state
const errors = reactive({
    title: '',
    introduction: '',
    selectedMedia: '',
    discount: '',
    head_images: '', // Add head images validation
});

const headImageUrls = ref([]); // Store preview URLs

// Media selection dialog state
const mediaDialogVisible = ref(false);
const selectedMediaItems = ref([]);
const mediaLoading = ref(false);
const mediaGlobalFilter = ref('');

// Add pagination state for media dialog
const mediaFirst = ref(0);
const mediaRows = ref(10);
const mediaTotalRecords = ref(0);
const mediaCurrentPage = ref(1);

const mediaTotalPages = computed(() => {
    return Math.ceil(mediaTotalRecords.value / mediaRows.value);
});

// Sample media data - in a real app, this would come from an API
const mediaItems = ref([]);

// Add media selection target
const mediaSelectionTarget = ref('content'); // 'content' or 'headImages'

// Fetch post data by ID
const fetchPost = async (id) => {
    loading.value = true;
    try {
        const response = await postService.getPost(id);
        if (response.status !== 200) {
            toast.add({ severity: 'error', summary: '错误', detail: response.message, life: 3000 });
            router.push('/posts');
            return;
        }

        const postData = response.data;
        post.id = postData.id;
        post.title = postData.title;
        post.price = postData.price;
        post.discount = postData.discount || 100;
        post.introduction = postData.description;
        post.status = postData.status;
        post.selectedMedia = postData.medias || [];
        post.medias = postData.medias?.map(media => media.id) || [];
        post.head_images = postData.head_images || []; // Add head images
        loadHeadImagePreviews(); // Load head image previews
    } catch (error) {
        toast.add({ severity: 'error', summary: '错误', detail: '加载曲谱失败', life: 3000 });
        router.push('/posts');
    } finally {
        loading.value = false;
    }
};

// Open media selection dialog
const openMediaDialog = async (target = 'content') => {
    mediaSelectionTarget.value = target;
    mediaDialogVisible.value = true;
    mediaCurrentPage.value = 1;
    mediaFirst.value = 0;
    await loadMediaItems();

    // Set selected items based on target and match with loaded media items
    const selectedIds = target === 'headImages' ? post.head_images : post.selectedMedia.map(m => m.id);
    selectedMediaItems.value = mediaItems.value.filter(item => selectedIds.includes(item.id));
};

// Load media items
const loadMediaItems = async () => {
    mediaLoading.value = true;
    try {
        const response = await mediaService.getMedias({
            page: mediaCurrentPage.value,
            limit: mediaRows.value
        });
        mediaItems.value = response.data.items;
        mediaTotalRecords.value = response.data.total;
    } catch (error) {
        toast.add({ severity: 'error', summary: '错误', detail: '加载媒体文件失败', life: 3000 });
    } finally {
        mediaLoading.value = false;
    }
};

// Confirm media selection
const confirmMediaSelection = () => {
    if (selectedMediaItems.value.length) {
        if (mediaSelectionTarget.value === 'headImages') {
            if (selectedMediaItems.value.length > 3) {
                toast.add({ severity: 'warn', summary: '提示', detail: '展示图片最多选择3张', life: 3000 });
                return;
            }
            // Store only IDs
            post.head_images = selectedMediaItems.value.map(item => item.id);
            errors.head_images = '';
            loadHeadImagePreviews();
        } else {
            post.selectedMedia = [...selectedMediaItems.value];
            errors.selectedMedia = '';
        }
    }
    mediaDialogVisible.value = false;
};

// Cancel media selection
const cancelMediaSelection = () => {
    mediaDialogVisible.value = false;
};

// Remove a selected media item
const removeMedia = (media) => {
    const index = post.selectedMedia.findIndex(item => item.id === media.id);
    if (index > -1) {
        post.selectedMedia.splice(index, 1);
    }
};

// Remove a selected head image
const removeHeadImage = (mediaId) => {
    const index = post.head_images.indexOf(mediaId);
    if (index > -1) {
        post.head_images.splice(index, 1);
        loadHeadImagePreviews();
    }
};

// Load head image previews
const loadHeadImagePreviews = async () => {
    headImageUrls.value = [];
    for (const mediaId of post.head_images) {
        try {
            const url = await mediaService.getMediaPreviewUrl(mediaId);
            headImageUrls.value.push({ id: mediaId, url });
        } catch (error) {
            console.error('Failed to load preview for media:', mediaId);
        }
    }
};

// Save the post
const savePost = async () => {
    // Reset errors
    Object.keys(errors).forEach(key => errors[key] = '');

    // Validate form
    let valid = true;

    if (!post.title.trim()) {
        errors.title = '请填写曲谱标题';
        valid = false;
    }

    // if (!post.introduction.trim()) {
    //     errors.introduction = '请填写曲谱介绍';
    //     valid = false;
    // }

    if (post.selectedMedia.length === 0) {
        errors.selectedMedia = '请选择至少一个媒体文件';
        valid = false;
    }

    if (post.discount < 0 || post.discount > 100) {
        errors.discount = '折扣必须在0到100之间';
        valid = false;
    }

    if (post.head_images.length === 0) {
        errors.head_images = '请选择至少一张展示图片';
        valid = false;
    }

    if (!valid) {
        toast.add({ severity: 'error', summary: '表单错误', detail: '请检查表单中的错误并修正', life: 3000 });
        return;
    }

    try {
        post.medias = post.selectedMedia.map(media => media.id);
        // Remove head_image_ids, use head_images directly since it now contains IDs
        const resp = await postService.updatePost(post.id, post);

        if (resp.status !== 200) {
            toast.add({ severity: 'error', summary: '错误', detail: resp.message, life: 3000 });
            return;
        }

        toast.add({ severity: 'success', summary: '成功', detail: '曲谱已成功更新', life: 3000 });
        router.push('/posts');
    } catch (error) {
        toast.add({ severity: 'error', summary: '错误', detail: '更新曲谱失败', life: 3000 });
    }
};

// Cancel and go back to post list
const cancelEdit = () => {
    router.push('/posts');
};


// Add pagination handler
const onMediaPage = (event) => {
    mediaFirst.value = event.first;
    mediaRows.value = event.rows;
    mediaCurrentPage.value = Math.floor(event.first / event.rows) + 1;
    loadMediaItems();
};

onMounted(() => {
    // Get post ID from route params
    const postId = route.params.id;
    if (postId) {
        fetchPost(postId);
    } else {
        toast.add({ severity: 'error', summary: '错误', detail: '未提供曲谱ID', life: 3000 });
        router.push('/posts');
    }
});
</script>
<template>
    <Toast />

    <div class="w-full max-w-6xl mx-auto">
        <div class="flex justify-between items-center mb-6">
            <h1 class="text-2xl font-bold text-gray-800">编辑曲谱</h1>
            <div class="flex gap-2">
                <Button label="取消" icon="pi pi-times" severity="secondary" @click="cancelEdit" />
                <Button label="保存" icon="pi pi-check" severity="primary" @click="savePost" />
            </div>
        </div>

        <div v-if="loading" class="flex flex-col items-center justify-center py-12">
            <ProgressSpinner style="width:50px;height:50px" />
            <span class="mt-4">加载曲谱数据...</span>
        </div>

        <div v-else>
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <!-- Add Head Images Selection before Title -->
                <div class="col-span-2">
                    <label class="block text-sm font-medium text-gray-700 mb-1">
                        展示图片 <span class="text-gray-500 text-xs">(最多3张)</span>
                    </label>
                    <div class="p-4 border border-gray-200 rounded-md">
                        <div v-if="post.head_images.length === 0"
                            class="flex justify-center items-center flex-col space-y-3 py-6">
                            <i class="pi pi-image text-gray-400 text-5xl!"></i>
                            <p class="text-gray-500">请选择展示图片</p>
                            <Button label="选择图片" icon="pi pi-plus" @click="openMediaDialog('headImages')" outlined />
                            <small v-if="errors.head_images" class="text-red-500">{{ errors.head_images }}</small>
                        </div>
                        <div v-else>
                            <div class="mb-4 flex justify-between items-center">
                                <Button label="更换图片" icon="pi pi-plus" @click="openMediaDialog('headImages')"
                                    :disabled="post.head_images.length >= 3" outlined />
                                <span class="text-sm text-gray-500">
                                    {{ post.head_images.length }}/3
                                </span>
                            </div>
                            <div class="grid grid-cols-2 md:grid-cols-3 gap-4">
                                <div v-for="(mediaId, index) in post.head_images" :key="mediaId"
                                    class="relative aspect-video">
                                    <img v-if="headImageUrls[index]" :src="headImageUrls[index].url"
                                        class="w-full h-full object-cover rounded bg-gray-200" :alt="mediaId">
                                    <Button icon="pi pi-times"
                                        class="absolute! top-2 right-2 p-button-rounded p-button-danger p-button-sm"
                                        @click="removeHeadImage(mediaId)" />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Title -->
                <div class="col-span-2">
                    <label for="title" class="block text-sm font-medium text-gray-700 mb-1">标题</label>
                    <InputText id="title" v-model="post.title" class="w-full p-inputtext-lg" placeholder="输入曲谱标题" />
                    <small v-if="errors.title" class="text-red-500">{{ errors.title }}</small>
                </div>

                <!-- Price -->
                <div class="col-span-1">
                    <label for="price" class="block text-sm font-medium text-gray-700 mb-1">价格 (分)</label>
                    <InputNumber id="price" v-model="post.price" :minFractionDigits="0" :maxFractionDigits="0"
                        class="w-full" placeholder="输入价格，单位：分" />
                </div>

                <!-- Discount -->
                <div class="col-span-1">
                    <label for="discount" class="block text-sm font-medium text-gray-700 mb-1">折扣 (%)</label>
                    <InputNumber id="discount" v-model="post.discount" :min="0" :max="100" :minFractionDigits="0"
                        :maxFractionDigits="0" class="w-full" placeholder="输入折扣百分比" />
                    <small v-if="errors.discount" class="text-red-500">{{ errors.discount }}</small>
                </div>

                <!-- Status -->
                <div class="col-span-2">
                    <label class="block text-sm font-medium text-gray-700 mb-1">状态</label>
                    <div class="flex gap-4">
                        <div v-for="option in statusOptions" :key="option.value" class="flex items-center">
                            <RadioButton :value="option.value" v-model="post.status"
                                :inputId="'status_' + option.value" />
                            <label :for="'status_' + option.value" class="ml-2">{{ option.label }}</label>
                        </div>
                    </div>
                </div>

                <!-- Introduction -->
                <div class="col-span-2">
                    <label for="introduction" class="block text-sm font-medium text-gray-700 mb-1">曲谱介绍</label>
                    <Textarea id="introduction" v-model="post.introduction" rows="5" class="w-full"
                        placeholder="输入曲谱介绍内容" />
                    <small v-if="errors.introduction" class="p-error">{{ errors.introduction }}</small>
                </div>

                <!-- Media Selection -->
                <div class="col-span-2">
                    <label class="block text-sm font-medium text-gray-700 mb-1">媒体资源</label>
                    <div class="p-4 border border-gray-200 rounded-md">
                        <div v-if="post.selectedMedia.length === 0"
                            class="flex justify-center items-center flex-col space-y-3 py-6">
                            <i class="pi pi-image text-gray-400 text-3xl"></i>
                            <p class="text-gray-500">尚未选择任何媒体文件</p>
                            <Button label="选择媒体" icon="pi pi-plus" @click="openMediaDialog" outlined />
                            <small v-if="errors.selectedMedia" class="p-error">{{ errors.selectedMedia }}</small>
                        </div>
                        <div v-else>
                            <div class="mb-4">
                                <Button label="更改媒体" icon="pi pi-sync" @click="openMediaDialog" outlined />
                            </div>
                            <div class="grid grid-cols-1 md:grid-cols-1 gap-3">
                                <div v-for="media in post.selectedMedia" :key="media.id"
                                    class="relative border border-gray-200 rounded-md p-2 flex items-center">
                                    <div
                                        class="flex-shrink-0 h-10 w-10 mr-3 bg-gray-100 rounded flex items-center justify-center">
                                        <component :is="getFileIcon(media, icons)" class="text-xl text-gray-600" />
                                    </div>

                                    <div class="flex-1 overflow-hidden">
                                        <div class="text-sm font-medium text-gray-900 truncate">{{ media.name }}
                                        </div>

                                        <!-- <Badge :value="getFileTypeByMimeCN(media.mime_type)" /> -->

                                        <div class="flex gap-2">
                                            <Badge :value="getFileTypeByMimeCN(media.mime_type)" />
                                            <Badge v-if="media.metas?.short" severity="warn" value="试听" />
                                            <Badge v-if="media.metas?.duration" severity="secondary"
                                                :value="'时长：' + formatDuration(media.metas?.duration)" />
                                        </div>
                                    </div>
                                    <Button icon="pi pi-times" class="p-button-rounded p-button-text p-button-sm"
                                        @click="removeMedia(media)" aria-label="移除" />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Media Selection Dialog -->
    <Dialog v-model:visible="mediaDialogVisible" header="选择媒体" :modal="true" :dismissableMask="true" :closable="true"
        :style="{ width: '80vw' }" :breakpoints="{ '960px': '90vw' }">
        <div class="mb-4">
            <InputText v-model="mediaGlobalFilter" placeholder="搜索媒体..." class="w-full" />
        </div>

        <DataTable v-model:selection="selectedMediaItems" :value="mediaItems" :loading="mediaLoading" dataKey="id"
            :paginator="true" v-model:first="mediaFirst" v-model:rows="mediaRows" :totalRecords="mediaTotalRecords"
            @page="onMediaPage" selectionMode="multiple"
            paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport"
            :rows-per-page-options="[10, 25, 50]" currentPageReportTemplate="第 {first} 到 {last} 条，共 {totalRecords} 条"
            :lazy="true" :showCurrentPageReport="true">

            <template #paginatorLeft>
                <div class="flex items-center">
                    每页: {{ mediaRows }}
                </div>
            </template>
            <template #paginatorRight>
                <div class="flex items-center">
                    第 {{ mediaCurrentPage }} 页，共 {{ mediaTotalPages }} 页
                </div>
            </template>

            <template #empty>
                <div class="text-center p-4">没有可用的媒体文件</div>
            </template>

            <template #loading>
                <div class="flex flex-col items-center justify-center p-4">
                    <ProgressSpinner style="width:50px;height:50px" />
                    <span class="mt-2">加载媒体数据...</span>
                </div>
            </template>

            <Column selectionMode="multiple" style="width: 3rem"></Column>

            <Column field="fileName" header="文件名">
                <template #body="{ data }">
                    <div class="text-sm font-medium text-gray-900">{{ data.name }}</div>
                </template>
            </Column>

            <Column field="fileType" header="文件类型">
                <template #body="{ data }">
                    <Badge :value="getFileTypeByMimeCN(data.mime_type)" />
                </template>
            </Column>

            <Column field="fileSize" header="文件大小">
                <template #body="{ data }">
                    {{ formatFileSize(data.size) }}
                </template>
            </Column>

            <Column field="createdAt" header="上传时间">
                <template #body="{ data }">
                    {{ formatDate(data.upload_time) }}
                </template>
            </Column>
        </DataTable>

        <template #footer>
            <Button label="取消" icon="pi pi-times" @click="cancelMediaSelection" class="p-button-text" />
            <Button label="确认选择" icon="pi pi-check" @click="confirmMediaSelection"
                :disabled="selectedMediaItems.length === 0" />
        </template>
    </Dialog>
</template>
