<script setup>
    import { computed, onMounted, reactive, ref, watch } from 'vue';
    import { useRoute } from 'vue-router';
    import { useI18n } from 'vue-i18n';
    import { useWorkspaceStore } from '@/features/workspaces/stores/workspaceStore.js';
    import { useChannelsStore } from '@/features/channels/stores/channelsStore.js';
    import {
        mdiClose,
        mdiFacebook,
        mdiImage,
        mdiInstagram,
        mdiLinkedin,
        mdiMusicNote,
        mdiOpenInNew,
        mdiPencil,
        mdiPlus,
        mdiReddit,
        mdiContentSave,
        mdiWeb,
        mdiYoutube,
    } from '@mdi/js';

    const route = useRoute();
    const { t } = useI18n();
    const workspaceStore = useWorkspaceStore();
    const channelsStore = useChannelsStore();

    const isCreateFormVisible = ref(false);
    const editingChannelId = ref('');
    const formError = ref(null);
    const activeNetwork = ref('Instagram');
    const form = reactive({
        name: '',
        network: 'Instagram',
        handle: '',
        externalUrl: '',
        portraitUrl: '',
        bannerUrl: '',
    });

    const networkOptions = [
        { value: 'Instagram', icon: mdiInstagram },
        { value: 'TikTok', icon: mdiMusicNote },
        { value: 'Facebook', icon: mdiFacebook },
        { value: 'LinkedIn', icon: mdiLinkedin },
        { value: 'YouTube', icon: mdiYoutube },
        { value: 'X', icon: mdiClose },
        { value: 'Reddit', icon: mdiReddit },
        { value: 'Website', icon: mdiWeb },
    ];

    const configuredChannels = computed(() =>
        channelsStore.channels
            .filter(channel => channel.network)
            .map(channel => {
                const workspace = workspaceStore.workspaces.find(candidate => candidate.id === channel.workspaceId);

                return {
                    ...channel,
                    workspaceName: workspace?.name ?? t('nav.noWorkspace'),
                };
            })
    );

    const channelsForActiveNetwork = computed(() =>
        configuredChannels.value.filter(channel => channel.network === activeNetwork.value)
    );
    const editingChannel = computed(() =>
        configuredChannels.value.find(channel => channel.id === editingChannelId.value) ?? null
    );
    const previewChannel = computed(() => ({
        name: form.name.trim() || `${form.network} channel`,
        network: form.network,
        handle: form.handle.trim(),
        externalUrl: form.externalUrl.trim(),
        portraitUrl: form.portraitUrl.trim(),
        bannerUrl: form.bannerUrl.trim(),
        workspaceName: workspaceStore.activeWorkspace?.name ?? t('nav.noWorkspace'),
    }));

    function resetForm() {
        form.name = '';
        form.network = activeNetwork.value;
        form.handle = '';
        form.externalUrl = '';
        form.portraitUrl = '';
        form.bannerUrl = '';
        formError.value = null;
    }

    function openCreateForm(network = activeNetwork.value) {
        activeNetwork.value = network;
        resetForm();
        form.network = network;
        editingChannelId.value = '';
        isCreateFormVisible.value = true;
    }

    function openEditForm(channel) {
        activeNetwork.value = channel.network;
        editingChannelId.value = channel.id;
        form.name = channel.name ?? '';
        form.network = channel.network ?? activeNetwork.value;
        form.handle = channel.handle ?? '';
        form.externalUrl = channel.externalUrl ?? '';
        form.portraitUrl = channel.portraitUrl ?? '';
        form.bannerUrl = channel.bannerUrl ?? '';
        formError.value = null;
        isCreateFormVisible.value = true;
    }

    function selectNetwork(network) {
        activeNetwork.value = network;

        if (isCreateFormVisible.value) {
            form.network = network;
        }
    }

    async function submitForm() {
        formError.value = null;

        try {
            const payload = {
                name: form.name,
                network: form.network,
                handle: form.handle,
                externalUrl: form.externalUrl,
                portraitUrl: form.portraitUrl,
                bannerUrl: form.bannerUrl,
            };

            if (editingChannelId.value) {
                await channelsStore.updateChannel(editingChannelId.value, {
                    id: editingChannelId.value,
                    workspaceId: editingChannel.value?.workspaceId ?? workspaceStore.activeWorkspaceId,
                    ...payload,
                });
            } else {
                await channelsStore.createChannel(payload);
            }

            activeNetwork.value = form.network;
            isCreateFormVisible.value = false;
            editingChannelId.value = '';
            resetForm();
        } catch (error) {
            formError.value = error.message ?? t('channels.errors.createFailed');
        }
    }

    function channelHandle(channel) {
        const rawHandle = channel.handle || channel.name || channel.network;

        if (channel.network === 'Website') {
            return channel.externalUrl || rawHandle;
        }

        return rawHandle.startsWith('@') ? rawHandle : `@${rawHandle.replace(/\s+/g, '').toLowerCase()}`;
    }

    function channelInitials(channel) {
        const source = channel.name || channel.network || '';
        const words = source.split(/\s+/).filter(Boolean);
        const initials = words.slice(0, 2).map(word => word[0]).join('');

        return initials.toUpperCase() || channel.network.slice(0, 2).toUpperCase();
    }

    function networkIcon(network) {
        return networkOptions.find(option => option.value === network)?.icon ?? mdiWeb;
    }

    function networkClass(network) {
        return `network-${(network ?? 'other').toLowerCase().replace(/[^a-z0-9]+/g, '-')}`;
    }

    async function uploadChannelImage(channel, imageKind, event) {
        const [file] = Array.from(event.target.files ?? []);
        event.target.value = '';

        if (!file || !channel) {
            return;
        }

        formError.value = null;

        try {
            const updated = await channelsStore.uploadChannelImage(channel.id, imageKind, file);
            if (editingChannelId.value === channel.id && updated) {
                form.portraitUrl = updated.portraitUrl ?? '';
                form.bannerUrl = updated.bannerUrl ?? '';
            }
        } catch (error) {
            formError.value = error.message ?? t('channels.errors.updateFailed');
        }
    }

    watch(
        () => route.query.create,
        createValue => {
            if (createValue === 'true') {
                openCreateForm(activeNetwork.value);
            }
        },
        { immediate: true }
    );

    onMounted(() => {
        channelsStore.fetchChannels();
    });

    watch(
        () => [route.query.channel, channelsStore.channels.length],
        ([channelId]) => {
            const selected = channelsStore.channels.find(channel => channel.id === channelId);
            if (selected?.network) {
                activeNetwork.value = selected.network;
            }
        },
        { immediate: true }
    );
</script>

<template>
    <section class="page-shell">
        <div class="header">
            <h1>{{ t('channels.title') }}</h1>
            <p>{{ t('channels.description') }}</p>
        </div>

        <div class="network-tabs">
            <v-btn variant="text" :ripple="false"
                v-for="network in networkOptions"
                :key="network.value"
                type="button"
                class="network-tab"
                :class="{ active: activeNetwork === network.value }"
                :title="network.value"
                :aria-label="network.value"
                @click="selectNetwork(network.value)"
            >
                <v-icon :icon="network.icon" />
            </v-btn>
        </div>

        <section
            v-if="isCreateFormVisible"
            class="create-panel"
        >
            <article
                class="channel-preview-card create-preview"
                :class="networkClass(form.network)"
            >
                <div class="channel-banner">
                    <img
                        v-if="previewChannel.bannerUrl"
                        :src="previewChannel.bannerUrl"
                        :alt="`${previewChannel.name} banner`"
                    />
                    <v-icon
                        v-else
                        class="banner-network-icon"
                        :icon="networkIcon(form.network)"
                    />
                </div>
                <div class="channel-profile-row">
                    <div class="channel-portrait">
                        <img
                            v-if="previewChannel.portraitUrl"
                            :src="previewChannel.portraitUrl"
                            :alt="`${previewChannel.name} portrait`"
                        />
                        <span v-else>{{ channelInitials(previewChannel) }}</span>
                    </div>
                    <div>
                        <strong>{{ previewChannel.name }}</strong>
                        <span>{{ channelHandle(previewChannel) }}</span>
                    </div>
                </div>
                <p>{{ previewChannel.workspaceName }}</p>
            </article>

            <form
                class="create-form"
                @submit.prevent="submitForm"
            >
                <div class="panel-header">
                    <strong>{{ editingChannelId ? t('channels.editTitle') : t('channels.createTitle') }}</strong>
                    <span>{{ form.network }}</span>
                </div>

                <div
                    v-if="formError"
                    class="page-message error"
                >
                    {{ formError }}
                </div>

                <div class="form-grid">
                    <v-select
                        v-model="form.network"
                        :items="networkOptions.map(option => option.value)"
                        :label="t('channels.fields.network')"
                        variant="outlined"
                        hide-details
                    />
                    <v-text-field
                        v-model="form.name"
                        :label="t('channels.fields.name')"
                        variant="outlined"
                        hide-details
                    />
                    <v-text-field
                        v-model="form.handle"
                        :label="t('channels.fields.handle')"
                        variant="outlined"
                        hide-details
                    />
                    <v-text-field
                        v-model="form.externalUrl"
                        :label="t('channels.fields.externalUrl')"
                        variant="outlined"
                        hide-details
                    />
                    <v-text-field
                        v-model="form.portraitUrl"
                        :label="t('channels.fields.portraitUrl')"
                        variant="outlined"
                        hide-details
                    />
                    <v-text-field
                        v-model="form.bannerUrl"
                        :label="t('channels.fields.bannerUrl')"
                        variant="outlined"
                        hide-details
                    />
                </div>

                <div
                    v-if="editingChannelId"
                    class="image-upload-row"
                >
                    <label class="image-upload-button">
                        <v-icon :icon="mdiImage" />
                        <span>{{ t('channels.actions.changePortrait') }}</span>
                        <input
                            type="file"
                            accept="image/png,image/jpeg,image/jpg,image/gif,image/webp"
                            :disabled="channelsStore.isUpdating"
                            @change="uploadChannelImage(editingChannel, 'portrait', $event)"
                        />
                    </label>
                    <label class="image-upload-button">
                        <v-icon :icon="mdiImage" />
                        <span>{{ t('channels.actions.changeBanner') }}</span>
                        <input
                            type="file"
                            accept="image/png,image/jpeg,image/jpg,image/gif,image/webp"
                            :disabled="channelsStore.isUpdating"
                            @change="uploadChannelImage(editingChannel, 'banner', $event)"
                        />
                    </label>
                </div>

                <div class="panel-actions">
                    <v-btn variant="text" :ripple="false"
                        class="secondary"
                        type="button"
                        @click="isCreateFormVisible = false"
                    >
                        {{ t('common.cancel') }}
                    </v-btn>
                    <v-btn variant="text" :ripple="false"
                        class="primary"
                        type="submit"
                        :disabled="channelsStore.isCreating || channelsStore.isUpdating"
                    >
                        <v-icon :icon="editingChannelId ? mdiContentSave : mdiPlus" />
                        <span>
                            {{ channelsStore.isCreating || channelsStore.isUpdating ? t('common.saving') : (editingChannelId ? t('channels.saveChanges') : t('channels.createTitle')) }}
                        </span>
                    </v-btn>
                </div>
            </form>
        </section>

        <div
            v-if="channelsStore.isLoading"
            class="page-message"
        >
            {{ t('loading') }}
        </div>

        <div
            v-else-if="channelsStore.error"
            class="page-message error"
        >
            {{ channelsStore.error }}
        </div>

        <div
            v-else-if="channelsForActiveNetwork.length"
            class="channel-grid"
        >
            <article
                v-for="channel in channelsForActiveNetwork"
                :key="channel.id"
                class="channel-preview-card"
                :class="networkClass(channel.network)"
            >
                <div class="channel-banner">
                    <img
                        v-if="channel.bannerUrl"
                        :src="channel.bannerUrl"
                        :alt="`${channel.name} banner`"
                    />
                    <v-icon
                        v-else
                        class="banner-network-icon"
                        :icon="networkIcon(channel.network)"
                    />
                    <button
                        class="channel-edit-button"
                        type="button"
                        :aria-label="`${t('channels.editTitle')} ${channel.name}`"
                        @click="openEditForm(channel)"
                    >
                        <v-icon :icon="mdiPencil" />
                    </button>
                    <a
                        v-if="channel.externalUrl"
                        :href="channel.externalUrl"
                        target="_blank"
                        rel="noreferrer"
                        :aria-label="channel.externalUrl"
                    >
                        <v-icon :icon="mdiOpenInNew" />
                    </a>
                </div>

                <div class="channel-profile-row">
                    <div class="channel-portrait">
                        <img
                            v-if="channel.portraitUrl"
                            :src="channel.portraitUrl"
                            :alt="`${channel.name} portrait`"
                        />
                        <span v-else>{{ channelInitials(channel) }}</span>
                    </div>
                    <div>
                        <strong>{{ channel.name }}</strong>
                        <span>{{ channelHandle(channel) }}</span>
                    </div>
                </div>

                <p>{{ channel.workspaceName }}</p>
            </article>
        </div>

        <v-btn variant="text" :ripple="false"
            v-else
            type="button"
            class="empty-state"
            @click="openCreateForm(activeNetwork)"
        >
            <v-icon :icon="mdiPlus" />
            <span>{{ t('channels.emptyAction', { network: activeNetwork }) }}</span>
        </v-btn>
    </section>
</template>

<style scoped>
@reference "@/assets/main.css";
    .page-shell {
        @apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
    }

    .header h1 {
        @apply text-4xl font-black;
        color: var(--app-color-on-surface);
    }

    .header p,
    .channel-profile-row span,
    .page-message,
    .empty-state span {
        @apply text-sm leading-6 not-italic;
        color: var(--app-text-muted);
    }

    .network-tabs {
        @apply flex flex-wrap gap-2;
    }

    .network-tab {
        @apply grid h-11 w-11 place-items-center rounded-full border p-0 transition;
        border-color: var(--app-border-subtle);
        background: rgba(255, 255, 255, 0.95);
        color: var(--app-text-muted);
    }

    .network-tab.active,
    .network-tab:hover {
        border-color: rgba(15, 118, 110, 0.24);
        background: rgba(15, 118, 110, 0.1);
        color: var(--app-color-on-surface);
    }

    .channel-grid {
        @apply grid gap-4 sm:grid-cols-2 xl:grid-cols-4;
    }

    .channel-preview-card,
    .empty-state {
        @apply flex flex-col gap-5 rounded-[1.5rem] border p-5;
        background: rgba(255, 255, 255, 0.92);
        border-color: var(--app-border-subtle);
    }

    .create-panel {
        @apply grid gap-5 rounded-[1.5rem] border p-5 lg:grid-cols-[minmax(18rem,0.85fr)_minmax(0,1.15fr)];
        background: rgba(255, 255, 255, 0.92);
        border-color: var(--app-border-subtle);
    }

    .create-form {
        @apply flex flex-col gap-5;
    }

    .empty-state {
        @apply items-center justify-center text-center;
    }

    .create-button,
    .primary,
    .secondary {
        @apply inline-flex items-center justify-center rounded-full px-5 py-3 text-sm font-bold transition;
    }

    .primary {
        @apply gap-2;
        background: var(--app-color-on-surface);
        color: var(--app-color-on-primary);
    }

    .secondary {
        background: var(--app-control-hover);
        color: var(--app-color-on-surface);
    }

    .panel-header {
        @apply flex items-center justify-between gap-4;
    }

    .panel-header strong,
    .field,
    .channel-profile-row strong {
        color: var(--app-color-on-surface);
    }

    .panel-header span {
        @apply text-sm font-semibold;
        color: var(--app-text-muted);
    }

    .form-grid {
        @apply grid gap-4;
    }

    .image-upload-row {
        @apply flex flex-wrap gap-2;
    }

    .image-upload-button {
        @apply inline-flex min-h-10 cursor-pointer items-center gap-2 rounded-full border px-4 text-sm font-bold;
        background: var(--app-control-hover);
        border-color: var(--app-border-subtle);
        color: var(--app-color-on-surface);
    }

    .image-upload-button input {
        @apply sr-only;
    }

    .field {
        @apply flex flex-col gap-2 text-sm font-semibold;
    }

    .field input {
        @apply rounded-2xl border px-4 py-3 text-sm;
        border-color: var(--app-border-subtle);
        background: rgba(255, 255, 255, 0.95);
    }

    .panel-actions {
        @apply flex justify-end gap-3;
    }

    .channel-preview-card {
        @apply overflow-hidden p-0;
    }

    .channel-banner {
        @apply relative grid h-24 place-items-center;
        color: white;
    }

    .channel-banner img {
        @apply h-full w-full object-cover;
    }

    .banner-network-icon {
        @apply text-5xl opacity-90;
    }

    .channel-edit-button,
    .channel-banner a {
        @apply absolute right-3 top-3 grid h-8 w-8 place-items-center rounded-full;
        background: rgba(255, 255, 255, 0.18);
        color: white;
    }

    .channel-banner a {
        @apply top-12;
    }

    .channel-edit-button {
        @apply border-0;
    }

    .channel-profile-row {
        @apply -mt-9 flex items-end gap-3 px-5;
    }

    .channel-profile-row > div:last-child {
        @apply flex min-w-0 flex-col pb-1;
    }

    .channel-profile-row strong {
        @apply truncate text-lg font-black;
    }

    .channel-portrait {
        @apply grid h-16 w-16 shrink-0 place-items-center overflow-hidden rounded-full border-4 text-lg font-black shadow-sm;
        background: var(--app-color-on-primary);
        border-color: var(--app-color-on-primary);
        color: var(--app-color-on-surface);
    }

    .channel-portrait img {
        @apply h-full w-full object-cover;
    }

    .channel-preview-card > p {
        @apply px-5 pb-5 text-sm font-semibold;
        color: var(--app-text-muted);
    }

    .network-instagram .channel-banner {
        background: linear-gradient(135deg, #c13584, #f56040 54%, #ffdc80);
    }

    .network-tiktok .channel-banner {
        background: linear-gradient(135deg, #111827, #00f2ea 55%, #ff0050);
    }

    .network-facebook .channel-banner {
        background: linear-gradient(135deg, #1877f2, #0f766e);
    }

    .network-linkedin .channel-banner {
        background: linear-gradient(135deg, #0a66c2, #334155);
    }

    .network-youtube .channel-banner {
        background: linear-gradient(135deg, #ff0000, #111827);
    }

    .network-x .channel-banner {
        background: linear-gradient(135deg, #111827, #475569);
    }

    .network-reddit .channel-banner {
        background: linear-gradient(135deg, #ff4500, #f59e0b);
    }

    .network-website .channel-banner {
        background: linear-gradient(135deg, #0f766e, #2563eb);
    }

    .page-message {
        @apply rounded-[1.25rem] border p-4 font-medium;
        background: rgba(255, 255, 255, 0.84);
        border-color: var(--app-border-subtle);
    }

    .page-message.error {
        color: var(--app-danger-muted);
    }
</style>
