<script setup>
    import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue';
    import { useI18n } from 'vue-i18n';
    import { useRoute, useRouter } from 'vue-router';
    import { useSessionStorage } from '@vueuse/core';
    import {
        mdiArrowLeft,
        mdiCheckboxBlankOutline,
        mdiCheckboxMarked,
        mdiClose,
        mdiFacebook,
        mdiInstagram,
        mdiLinkedin,
        mdiMusicNote,
        mdiReddit,
        mdiTwitter,
        mdiWeb,
        mdiYoutube,
    } from '@mdi/js';
    import { useChannelsStore } from '@/features/channels/stores/channelsStore.js';
    import { useClientsStore } from '@/features/clients/stores/clientsStore.js';
    import ContentApprovalPanel from '@/features/content/components/ContentApprovalPanel.vue';
    import ContentCommentComposer from '@/features/content/components/ContentCommentComposer.vue';
    import ContentCommentFeed from '@/features/content/components/ContentCommentFeed.vue';
    import { useCalendarIntegrationsStore } from '@/features/content/stores/calendarIntegrationsStore.js';
    import { useContentItemDetailStore } from '@/features/content/stores/contentItemDetailStore.js';
    import { useContentItemsStore } from '@/features/content/stores/contentItemsStore.js';
    import { useCampaignsStore } from '@/features/campaigns/stores/campaignsStore.js';
    import { useWorkspaceStore } from '@/features/workspaces/stores/workspaceStore.js';

    const route = useRoute();
    const router = useRouter();
    const { locale, t } = useI18n();
    const workspaceStore = useWorkspaceStore();
    const campaignsStore = useCampaignsStore();
    const clientsStore = useClientsStore();
    const channelsStore = useChannelsStore();
    const calendarStore = useCalendarIntegrationsStore();
    const contentItemsStore = useContentItemsStore();
    const detailStore = useContentItemDetailStore();

    const editorDrafts = useSessionStorage('content-editor-drafts', {}, {
        mergeDefaults: true,
    });

    const form = reactive({
        title: '',
        campaignId: '',
        dueDate: '',
        body: '',
        hashtags: '',
        changeSummary: '',
        placements: [],
    });

    const assetForm = reactive({
        assetType: 'Image',
        displayName: '',
        googleDriveFileId: '',
        googleDriveLink: '',
        previewUrl: '',
    });

    const assetRevisionForms = reactive({});
    const activeProductionTab = ref('comments');
    const activeCalendarEvent = ref(null);
    const activePlacementId = ref('');
    const hashtagInput = ref('');

    const saveError = reactive({
        message: '',
    });

    const isCreateMode = computed(() => route.name === 'content-item-create');
    const contentItemId = computed(() => isCreateMode.value ? null : route.params.id);
    const item = computed(() => detailStore.item);
    const availableCampaigns = computed(() => campaignsStore.campaigns);
    const contentWorkspaceId = computed(() => item.value?.workspaceId ?? workspaceStore.activeWorkspaceId);
    const availableChannels = computed(() =>
        channelsStore.channels.filter(channel =>
            !contentWorkspaceId.value || channel.workspaceId === contentWorkspaceId.value
        )
    );
    const groupedChannels = computed(() => {
        const groups = new Map();

        for (const channel of availableChannels.value) {
            const network = channel.network || 'Other';
            const existing = groups.get(network) ?? [];
            existing.push(channel);
            groups.set(network, existing);
        }

        return Array.from(groups.entries()).map(([network, channels]) => ({
            network,
            channels,
        }));
    });
    const placementSummary = computed(() =>
        uniqueTargets(form.placements
            .map(placement => placement.channelName || placement.network)
            .filter(Boolean))
            .join(', ')
    );
    const selectedPlacements = computed(() =>
        form.placements.filter(placement => placement.channelId || placement.channelName || placement.network)
    );
    const activePlacement = computed(() => {
        if (!selectedPlacements.value.length) {
            return null;
        }

        return selectedPlacements.value.find(placement => placement.id === activePlacementId.value)
            ?? selectedPlacements.value[0];
    });
    const sharedPreviewText = computed(() => form.body.trim() || 'Draft the shared caption once. Every selected channel will preview this same content.');
    const sharedPreviewTags = computed(() => parseHashtags(form.hashtags));
    const workspaceHashtagFeed = computed(() => {
        const selected = new Set(sharedPreviewTags.value.map(tag => normalizeHashtag(tag).toLowerCase()));
        const feed = new Map();

        for (const contentItem of contentItemsStore.items) {
            if (
                contentWorkspaceId.value &&
                contentItem.workspaceId &&
                contentItem.workspaceId !== contentWorkspaceId.value
            ) {
                continue;
            }

            for (const tag of parseHashtags(contentItem.hashtags)) {
                const normalized = normalizeHashtag(tag);
                const key = normalized.toLowerCase();

                if (!normalized) {
                    continue;
                }

                const existing = feed.get(key) ?? {
                    tag: normalized,
                    count: 0,
                    isSelected: selected.has(key),
                };

                existing.count += 1;
                existing.isSelected = selected.has(key);
                feed.set(key, existing);
            }
        }

        return Array.from(feed.values())
            .sort((left, right) => right.count - left.count || left.tag.localeCompare(right.tag));
    });
    const hashtagSuggestions = computed(() =>
        workspaceHashtagFeed.value
            .filter(entry => !entry.isSelected)
            .slice(0, 12)
    );
    const operationalClient = computed(() => clientsStore.operationalClient);
    const campaignNameById = computed(() =>
        new Map(campaignsStore.campaigns.map(campaign => [campaign.id, campaign.name]))
    );
    const editorKey = computed(() => isCreateMode.value ? `new:${route.query.campaignId ?? 'default'}` : String(route.params.id));
    const approvalMode = computed(() => workspaceStore.activeWorkspace?.approvalMode ?? 'Required');
    const productionTabs = computed(() => [
        { key: 'comments', label: 'Comments', count: detailStore.comments.length },
        { key: 'revisions', label: 'Revisions', count: detailStore.revisions.length },
        { key: 'assets', label: 'Assets', count: detailStore.assets.length },
        { key: 'activity', label: 'Activity', count: detailStore.activity.length },
    ]);
    const workspaceMembers = computed(() =>
        contentWorkspaceId.value
            ? workspaceStore.membersByWorkspace[contentWorkspaceId.value] ?? []
            : []
    );
    const selectedDateKey = computed(() => /^\d{4}-\d{2}-\d{2}$/.test(form.dueDate) ? form.dueDate : '');
    const contextAnchorDate = computed(() => selectedDateKey.value ? parseDateKey(selectedDateKey.value) : startOfDay(new Date()));
    const calendarFetchRange = computed(() => {
        const start = startOfMonth(contextAnchorDate.value);
        const end = endOfMonth(contextAnchorDate.value);

        return {
            startDate: dateKey(addDays(start, -7)),
            endDate: dateKey(addDays(end, 7)),
        };
    });
    const visibleCalendarEventsByDate = computed(() => {
        const groups = new Map();

        for (const event of calendarStore.visibleEvents) {
            const key = dateKey(event.startDate);
            const existing = groups.get(key) ?? [];
            existing.push(event);
            groups.set(key, existing);
        }

        return groups;
    });
    const selectedDateCalendarEvents = computed(() =>
        selectedDateKey.value
            ? visibleCalendarEventsByDate.value.get(selectedDateKey.value) ?? []
            : []
    );
    const dateContextDays = computed(() => {
        const anchor = contextAnchorDate.value;

        return Array.from({ length: 7 }, (_, index) => {
            const date = addDays(anchor, index - 3);
            const key = dateKey(date);

            return {
                key,
                date,
                isSelected: key === selectedDateKey.value,
                events: visibleCalendarEventsByDate.value.get(key) ?? [],
            };
        });
    });

    function blankPlacement(channel = null) {
        return {
            id: crypto.randomUUID(),
            network: channel?.network ?? '',
            channelId: channel?.id ?? '',
            channelName: channel?.name ?? '',
            variantLabel: '',
            message: form.body,
            hashtags: form.hashtags,
            mediaItems: [],
        };
    }

    function blankMedia() {
        return {
            id: crypto.randomUUID(),
            mediaType: 'Image',
            label: '',
            url: '',
        };
    }

    function syncPlacementChannel(placement, value) {
        const channel = availableChannels.value.find(candidate => candidate.id === value);
        placement.channelId = value;
        placement.channelName = channel?.name ?? '';
        placement.network = channel?.network ?? placement.network;
    }

    function addPlacement(channel = null) {
        if (channel) {
            const existing = form.placements.find(placement => placement.channelId === channel.id);

            if (existing) {
                activePlacementId.value = existing.id;
                return;
            }
        }

        const placement = blankPlacement(channel);
        placement.message = form.body;
        placement.hashtags = form.hashtags;
        form.placements.push(placement);
        activePlacementId.value = placement.id;
    }

    function removePlacement(placementId) {
        form.placements = form.placements.filter(placement => placement.id !== placementId);

        if (activePlacementId.value === placementId) {
            activePlacementId.value = form.placements[0]?.id ?? '';
        }
    }

    function toggleChannel(channel) {
        const existing = form.placements.find(placement => placement.channelId === channel.id);

        if (existing) {
            removePlacement(existing.id);
            return;
        }

        addPlacement(channel);
    }

    function isChannelSelected(channelId) {
        return form.placements.some(placement => placement.channelId === channelId);
    }

    function setActivePlacement(placement) {
        activePlacementId.value = placement.id;
    }

    function addMedia(placement) {
        placement.mediaItems.push(blankMedia());
    }

    function removeMedia(placement, mediaId) {
        placement.mediaItems = placement.mediaItems.filter(media => media.id !== mediaId);
    }

    function removeHashtag(tagToRemove) {
        form.hashtags = parseHashtags(form.hashtags)
            .filter(tag => normalizeHashtag(tag).toLowerCase() !== normalizeHashtag(tagToRemove).toLowerCase())
            .join(' ');
    }

    function normalizeHashtag(value) {
        const cleaned = (value ?? '')
            .trim()
            .replace(/^#+/, '')
            .replace(/[^\p{L}\p{N}_-]/gu, '');

        return cleaned ? `#${cleaned}` : '';
    }

    function addHashtag(value) {
        const normalized = normalizeHashtag(value);

        if (!normalized) {
            return;
        }

        const tags = parseHashtags(form.hashtags);
        const exists = tags.some(tag => normalizeHashtag(tag).toLowerCase() === normalized.toLowerCase());

        if (!exists) {
            form.hashtags = [...tags, normalized].join(' ');
        }
    }

    function commitHashtagInput() {
        const entries = hashtagInput.value
            .split(/[,\s]+/)
            .map(entry => entry.trim())
            .filter(Boolean);

        for (const entry of entries) {
            addHashtag(entry);
        }

        hashtagInput.value = '';
    }

    function handleHashtagKeydown(event) {
        if (event.key === 'Enter' || event.key === ',' || event.key === 'Tab') {
            if (hashtagInput.value.trim()) {
                event.preventDefault();
                commitHashtagInput();
            }
        }

        if (event.key === 'Backspace' && !hashtagInput.value && sharedPreviewTags.value.length) {
            removeHashtag(sharedPreviewTags.value.at(-1));
        }
    }

    function handleHashtagPaste(event) {
        const pasted = event.clipboardData?.getData('text');

        if (!pasted || !/[\s,]/.test(pasted)) {
            return;
        }

        event.preventDefault();
        hashtagInput.value = pasted;
        commitHashtagInput();
    }

    function parseHashtags(value) {
        return (value ?? '')
            .split(/[,\s]+/)
            .map(tag => tag.trim())
            .filter(Boolean);
    }

    function uniqueTargets(targets) {
        const seen = new Set();
        const unique = [];

        for (const target of targets) {
            const normalized = target.trim();
            const key = normalized.toLowerCase();

            if (!normalized || seen.has(key)) {
                continue;
            }

            seen.add(key);
            unique.push(normalized);
        }

        return unique;
    }

    function parseTargets(value) {
        return uniqueTargets((value ?? '')
            .split(',')
            .map(entry => entry.trim())
            .filter(Boolean));
    }

    function normalizePlacements(placements) {
        const seen = new Set();
        const normalizedPlacements = [];

        for (const placement of placements) {
            const targetLabel = (placement.channelName || placement.network || '').trim();
            const knownChannel = channelsStore.channels.find(candidate =>
                candidate.id === placement.channelId ||
                candidate.name.toLowerCase() === targetLabel.toLowerCase()
            );
            const channel = availableChannels.value.find(candidate =>
                candidate.id === placement.channelId ||
                candidate.name.toLowerCase() === targetLabel.toLowerCase()
            );

            if (knownChannel && !channel) {
                continue;
            }

            const channelId = channel?.id ?? placement.channelId ?? '';
            const channelName = channel?.name ?? placement.channelName ?? '';
            const network = channel?.network ?? placement.network ?? '';
            const key = (channelName || network || placement.id || crypto.randomUUID()).toLowerCase();

            if ((channelName || network) && seen.has(key)) {
                continue;
            }

            seen.add(key);
            normalizedPlacements.push({
                id: placement.id ?? crypto.randomUUID(),
                network,
                channelId,
                channelName,
                variantLabel: placement.variantLabel ?? '',
                message: form.body,
                hashtags: form.hashtags,
                mediaItems: (placement.mediaItems ?? []).map(media => ({
                    id: media.id ?? crypto.randomUUID(),
                    mediaType: media.mediaType ?? 'Image',
                    label: media.label ?? '',
                    url: media.url ?? '',
                })),
            });
        }

        return normalizedPlacements;
    }

    function serializeDraft() {
        return JSON.parse(JSON.stringify({
            title: form.title,
            campaignId: form.campaignId,
            dueDate: form.dueDate,
            body: form.body,
            hashtags: form.hashtags,
            changeSummary: form.changeSummary,
            placements: form.placements.map(placement => ({
                ...placement,
                message: form.body,
                hashtags: form.hashtags,
            })),
        }));
    }

    function restoreDraft(draft) {
        form.title = draft.title ?? '';
        form.campaignId = draft.campaignId ?? availableCampaigns.value[0]?.id ?? '';
        form.dueDate = draft.dueDate ?? '';
        form.body = draft.body ?? '';
        form.hashtags = draft.hashtags ?? '';
        form.changeSummary = draft.changeSummary ?? '';
        form.placements = normalizePlacements(draft.placements ?? []);
        activePlacementId.value = form.placements[0]?.id ?? '';
    }

    function buildDraftFromItem() {
        const campaignId = item.value?.campaignId ?? '';
        const placements = parseTargets(item.value?.publicationTargets).map(target => {
            const channel = availableChannels.value.find(candidate => candidate.name.toLowerCase() === target.toLowerCase());

            return {
                id: crypto.randomUUID(),
                network: channel?.network ?? '',
                channelId: channel?.id ?? '',
                channelName: channel?.name ?? target,
                variantLabel: '',
                message: item.value?.publicationMessage ?? '',
                hashtags: item.value?.hashtags ?? '',
                mediaItems: [],
            };
        });

        restoreDraft({
            title: item.value?.title ?? '',
            campaignId,
            dueDate: item.value?.dueDate ? new Date(item.value.dueDate).toISOString().slice(0, 10) : '',
            body: item.value?.publicationMessage ?? '',
            hashtags: item.value?.hashtags ?? '',
            changeSummary: '',
            placements: placements.length ? placements : [blankPlacement()],
        });
    }

    function buildDraftForNew() {
        const campaignIdFromRoute = typeof route.query.campaignId === 'string' ? route.query.campaignId : '';
        const titleFromRoute = typeof route.query.title === 'string' ? route.query.title : '';
        const dateFromRoute = typeof route.query.date === 'string' ? route.query.date : '';

        restoreDraft({
            title: titleFromRoute,
            campaignId: availableCampaigns.value.some(campaign => campaign.id === campaignIdFromRoute)
                ? campaignIdFromRoute
                : availableCampaigns.value[0]?.id ?? '',
            dueDate: /^\d{4}-\d{2}-\d{2}$/.test(dateFromRoute) ? dateFromRoute : '',
            body: titleFromRoute,
            hashtags: '',
            changeSummary: '',
            placements: [],
        });
    }

    async function hydrateEditor() {
        saveError.message = '';

        if (isCreateMode.value) {
            const draft = editorDrafts.value[editorKey.value];
            if (draft) {
                restoreDraft(draft);
            } else {
                buildDraftForNew();
            }
            return;
        }

        if (!contentItemId.value) {
            return;
        }

        await detailStore.fetchContentItemDetail(contentItemId.value);

        const draft = editorDrafts.value[editorKey.value];
        if (draft) {
            restoreDraft(draft);
            return;
        }

        buildDraftFromItem();
    }

    function persistDraft() {
        editorDrafts.value = {
            ...editorDrafts.value,
            [editorKey.value]: serializeDraft(),
        };
    }

    function clearDraft(key = editorKey.value) {
        const nextDrafts = { ...editorDrafts.value };
        delete nextDrafts[key];
        editorDrafts.value = nextDrafts;
    }

    async function saveContent() {
        saveError.message = '';

        if (!form.title.trim() || !form.campaignId || !form.placements.length) {
            saveError.message = 'Title, campaign, and at least one channel are required.';
            return;
        }

        if (isCreateMode.value && !operationalClient.value?.id) {
            saveError.message = 'This workspace needs an operational account before content can be created.';
            return;
        }

        const payload = {
            title: form.title.trim(),
            campaignId: form.campaignId,
            publicationMessage: form.body.trim(),
            publicationTargets: placementSummary.value,
            hashtags: form.hashtags.trim(),
            dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,
        };

        if (isCreateMode.value) {
            try {
                const created = await contentItemsStore.createContentItem({
                    clientId: operationalClient.value.id,
                    ...payload,
                });

                editorDrafts.value = {
                    ...editorDrafts.value,
                    [String(created.id)]: serializeDraft(),
                };
                clearDraft();
                await router.replace({ name: 'content-item-detail', params: { id: created.id } });
            } catch (error) {
                saveError.message = 'The content item could not be created.';
            }
            return;
        }

        try {
            await detailStore.createRevision(contentItemId.value, {
                ...payload,
                changeSummary: form.changeSummary.trim() || 'Updated content plan',
            });

            persistDraft();
            form.changeSummary = '';
        } catch (error) {
            saveError.message = 'The content revision could not be saved.';
        }
    }

    async function submitDecision(approvalId, payload) {
        if (!contentItemId.value) {
            return;
        }

        await detailStore.submitDecision(contentItemId.value, approvalId, payload);
    }

    async function submitComment(payload) {
        if (!contentItemId.value || !payload?.body?.trim()) {
            return;
        }

        await detailStore.addComment(contentItemId.value, payload);
    }

    function inferGoogleDriveFileId(value) {
        const trimmed = value.trim();
        const filePathMatch = trimmed.match(/\/d\/([^/]+)/);
        const queryMatch = trimmed.match(/[?&]id=([^&]+)/);

        return filePathMatch?.[1] ?? queryMatch?.[1] ?? '';
    }

    function resetAssetForm() {
        assetForm.assetType = 'Image';
        assetForm.displayName = '';
        assetForm.googleDriveFileId = '';
        assetForm.googleDriveLink = '';
        assetForm.previewUrl = '';
    }

    async function linkGoogleDriveAsset() {
        if (!contentItemId.value || !assetForm.displayName.trim() || !assetForm.googleDriveLink.trim()) {
            return;
        }

        const googleDriveFileId = assetForm.googleDriveFileId.trim() || inferGoogleDriveFileId(assetForm.googleDriveLink);

        if (!googleDriveFileId) {
            saveError.message = 'A Google Drive file id is required when it cannot be read from the link.';
            return;
        }

        await detailStore.addGoogleDriveAsset(contentItemId.value, {
            assetType: assetForm.assetType,
            displayName: assetForm.displayName.trim(),
            googleDriveFileId,
            googleDriveLink: assetForm.googleDriveLink.trim(),
            previewUrl: assetForm.previewUrl.trim() || null,
        });
        resetAssetForm();
    }

    function assetRevisionForm(assetId) {
        if (!assetRevisionForms[assetId]) {
            assetRevisionForms[assetId] = {
                sourceReference: '',
                previewUrl: '',
                notes: '',
            };
        }

        return assetRevisionForms[assetId];
    }

    async function addAssetRevision(asset) {
        const draft = assetRevisionForm(asset.id);

        if (!contentItemId.value || !draft.sourceReference.trim()) {
            return;
        }

        await detailStore.addAssetRevision(contentItemId.value, asset.id, {
            sourceReference: draft.sourceReference.trim(),
            previewUrl: draft.previewUrl.trim() || null,
            notes: draft.notes.trim() || null,
        });

        assetRevisionForms[asset.id] = {
            sourceReference: '',
            previewUrl: '',
            notes: '',
        };
    }

    async function navigateBackToContent() {
        const returnTo = typeof route.query.returnTo === 'string' ? route.query.returnTo : '';
        const previousPath = router.options.history.state.back;

        if (returnTo.startsWith('/app/content')) {
            await router.push(returnTo);
            return;
        }

        if (typeof previousPath === 'string' && previousPath.startsWith('/app/content')) {
            router.back();
            return;
        }

        await router.push({ name: 'content-items' });
    }

    function showCalendarEvent(event) {
        activeCalendarEvent.value = {
            ...event,
            source: calendarStore.sourceById(event.calendarSourceId),
        };
    }

    function closeCalendarEvent() {
        activeCalendarEvent.value = null;
    }

    async function navigateToCalendarDay(event = activeCalendarEvent.value) {
        const targetDate = event?.startDate ? dateKey(event.startDate) : selectedDateKey.value;

        if (!targetDate) {
            return;
        }

        await router.push({
            name: 'content-items',
            query: {
                view: 'month',
                date: targetDate,
            },
        });
    }

    function selectContextDate(key) {
        form.dueDate = key;
    }

    function calendarEventSource(event) {
        return calendarStore.sourceById(event.calendarSourceId);
    }

    function calendarEventColor(event) {
        return calendarEventSource(event)?.color ?? 'var(--app-color-on-tertiary)';
    }

    function formatDateTime(value) {
        return value ? new Date(value).toLocaleString() : '';
    }

    function formatCalendarDate(value) {
        return value
            ? new Intl.DateTimeFormat(locale.value, { month: 'short', day: 'numeric', year: 'numeric' }).format(parseCalendarDate(value))
            : '';
    }

    function formatContextDay(date) {
        return new Intl.DateTimeFormat(locale.value, { weekday: 'short', day: 'numeric' }).format(date);
    }

    function channelIcon(network) {
        const normalized = (network ?? '').toLowerCase();

        if (normalized.includes('youtube')) {
            return mdiYoutube;
        }

        if (normalized === 'x' || normalized.includes('twitter')) {
            return mdiTwitter;
        }

        if (normalized.includes('instagram')) {
            return mdiInstagram;
        }

        if (normalized.includes('facebook')) {
            return mdiFacebook;
        }

        if (normalized.includes('linkedin')) {
            return mdiLinkedin;
        }

        if (normalized.includes('reddit')) {
            return mdiReddit;
        }

        if (normalized.includes('tiktok')) {
            return mdiMusicNote;
        }

        return mdiWeb;
    }

    function previewNetworkClass(network) {
        const normalized = (network ?? '').toLowerCase();

        if (normalized.includes('youtube')) {
            return 'youtube';
        }

        if (normalized === 'x' || normalized.includes('twitter')) {
            return 'x';
        }

        if (normalized.includes('instagram') || normalized.includes('tiktok')) {
            return 'vertical';
        }

        return 'standard';
    }

    function previewProfileName(placement = activePlacement.value) {
        return placement?.channelName || placement?.network || 'Selected channel';
    }

    function previewHandle(placement = activePlacement.value) {
        const channel = availableChannels.value.find(candidate => candidate.id === placement?.channelId);
        const handle = channel?.handle || placement?.channelName || placement?.network || 'channel';

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

    function startOfDay(value) {
        const date = new Date(value);
        date.setHours(0, 0, 0, 0);
        return date;
    }

    function startOfMonth(value) {
        const date = startOfDay(value);
        date.setDate(1);
        return date;
    }

    function endOfMonth(value) {
        const date = startOfMonth(value);
        date.setMonth(date.getMonth() + 1);
        date.setDate(0);
        return date;
    }

    function addDays(value, amount) {
        const date = startOfDay(value);
        date.setDate(date.getDate() + amount);
        return date;
    }

    function parseDateKey(value) {
        const [year, month, day] = value.split('-').map(Number);
        return new Date(year, month - 1, day);
    }

    function dateKey(value) {
        if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}/.test(value)) {
            return value.slice(0, 10);
        }

        const date = new Date(value);
        return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    }

    function parseCalendarDate(value) {
        if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}/.test(value)) {
            return parseDateKey(value.slice(0, 10));
        }

        return new Date(value);
    }

    watch(
        () => [
            isCreateMode.value,
            route.params.id,
            route.query.campaignId,
            availableCampaigns.value.length,
            availableChannels.value.length,
        ],
        async () => {
            await hydrateEditor();
        },
        { immediate: true }
    );

    watch(
        () => [
            contentWorkspaceId.value,
            calendarFetchRange.value.startDate,
            calendarFetchRange.value.endDate,
        ],
        async ([workspaceId, startDate, endDate]) => {
            if (!workspaceId) {
                return;
            }

            await Promise.all([
                contentItemsStore.fetchContentItems(),
                calendarStore.fetchSources(workspaceId),
                calendarStore.fetchEvents({ workspaceId, startDate, endDate }),
                workspaceStore.fetchMembers(workspaceId),
            ]);
        },
        { immediate: true }
    );

    watch(
        () => [
            form.title,
            form.campaignId,
            form.dueDate,
            form.body,
            form.hashtags,
            form.changeSummary,
            form.placements,
        ],
        () => {
            persistDraft();
        },
        { deep: true }
    );

    onBeforeUnmount(() => {
        detailStore.reset();
    });
</script>

<template>
    <section class="editor-shell">
        <v-btn variant="text" :ripple="false"
            class="back-button"
            type="button"
            @click="navigateBackToContent"
        >
            <v-icon :icon="mdiArrowLeft" />
            Back to content
        </v-btn>

        <div
            v-if="!isCreateMode && detailStore.isLoading"
            class="page-message"
        >
            Loading content item...
        </div>

        <div
            v-else-if="!isCreateMode && detailStore.error"
            class="page-message error"
        >
            {{ detailStore.error }}
        </div>

        <template v-else>
            <div class="editor-header">
                <div>
                    <div class="eyebrow">{{ isCreateMode ? 'New content' : 'Content item' }}</div>
                    <h1>{{ form.title || 'Untitled content' }}</h1>
                    <p>
                        {{ campaignNameById.get(form.campaignId) || 'Choose a campaign' }}
                        <template v-if="!isCreateMode && item">
                            · {{ item.status }}
                        </template>
                    </p>
                </div>

                <div class="header-actions">
                    <div
                        v-if="!isCreateMode && item"
                        class="status-badges"
                    >
                        <span class="meta-chip">{{ item.status }}</span>
                        <span class="meta-chip">{{ item.currentRevisionLabel }}</span>
                    </div>

                    <v-btn variant="text" :ripple="false"
                        class="primary-button"
                        :disabled="contentItemsStore.isCreating || detailStore.actions.revision"
                        @click="saveContent"
                    >
                        {{ isCreateMode
                            ? (contentItemsStore.isCreating ? 'Creating...' : 'Create content')
                            : (detailStore.actions.revision ? 'Saving...' : 'Save revision') }}
                    </v-btn>
                </div>
            </div>

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

            <div class="editor-grid">
                <section class="work-panel">
                    <ContentApprovalPanel
                        :approvals="detailStore.approvals"
                        :approval-mode="approvalMode"
                        :content-status="item?.status ?? 'Draft'"
                        :is-create-mode="isCreateMode"
                        :is-submitting-decision="detailStore.actions.decision"
                        @submit-decision="submitDecision"
                    />

                    <main class="content-panel">
                        <div class="content-section">
                            <div class="section-title-row">
                                <strong>Content</strong>
                                <span>{{ placementSummary || 'No channels selected yet' }}</span>
                            </div>

                            <div class="form-grid">
                                <v-text-field
                                    v-model="form.title"
                                    label="Title"
                                    variant="outlined"
                                    hide-details
                                />

                            <v-select
                                v-model="form.campaignId"
                                :items="availableCampaigns"
                                label="Campaign"
                                item-title="name"
                                item-value="id"
                                placeholder="Select a campaign"
                                variant="outlined"
                                hide-details
                            />

                            <v-text-field
                                v-model="form.dueDate"
                                label="Due date"
                                type="date"
                                variant="outlined"
                                hide-details
                            />

                            <div class="date-context field-wide">
                                <div class="date-context-days">
                                    <v-btn variant="text" :ripple="false"
                                        v-for="day in dateContextDays"
                                        :key="day.key"
                                        class="date-context-day"
                                        :class="{
                                            active: day.isSelected,
                                            marked: day.events.length,
                                        }"
                                        type="button"
                                        @click="selectContextDate(day.key)"
                                    >
                                        <span>{{ formatContextDay(day.date) }}</span>
                                        <strong>{{ day.events.length }}</strong>
                                    </v-btn>
                                </div>

                                <div
                                    v-if="selectedDateCalendarEvents.length"
                                    class="date-context-panel"
                                >
                                    <v-btn variant="text" :ripple="false"
                                        v-for="event in selectedDateCalendarEvents"
                                        :key="event.id"
                                        class="calendar-context-pill"
                                        :style="{ '--calendar-color': calendarEventColor(event) }"
                                        type="button"
                                        @click="showCalendarEvent(event)"
                                    >
                                        {{ event.title }}
                                    </v-btn>
                                </div>

                                <div
                                    v-else-if="selectedDateKey"
                                    class="date-context-empty"
                                >
                                    {{ t('contentItems.dateContext.noEvents') }}
                                </div>
                            </div>

                            <v-text-field
                                v-model="form.changeSummary"
                                class="field-wide"
                                label="Change summary"
                                placeholder="What changed in this revision?"
                                variant="outlined"
                                hide-details
                            />

                            <v-textarea
                                v-model="form.body"
                                class="field-wide"
                                label="Shared brief / base caption"
                                rows="4"
                                variant="outlined"
                                hide-details
                            />

                            <label class="field field-wide">
                                <span>Shared hashtags</span>
                                <div class="hashtags-input-shell">
                                    <div
                                        v-if="sharedPreviewTags.length"
                                        class="hashtags-editor"
                                    >
                                        <v-chip
                                            v-for="tag in sharedPreviewTags"
                                            :key="`form-${tag}`"
                                            class="hashtag-chip"
                                            size="small"
                                            rounded="pill"
                                            variant="tonal"
                                            color="deep-orange"
                                            closable
                                            @click:close="removeHashtag(tag)"
                                        >
                                            {{ tag.startsWith('#') ? tag : `#${tag}` }}
                                        </v-chip>
                                    </div>
                                    <input
                                        v-model="hashtagInput"
                                        class="hashtags-inline-input"
                                        type="text"
                                        placeholder="Add hashtag"
                                        @keydown="handleHashtagKeydown"
                                        @paste="handleHashtagPaste"
                                        @blur="commitHashtagInput"
                                    />
                                </div>

                                <div
                                    v-if="workspaceHashtagFeed.length"
                                    class="hashtag-feed"
                                >
                                    <div class="hashtag-feed-heading">
                                        <strong>Workspace hashtag feed</strong>
                                        <span>{{ workspaceHashtagFeed.length }} used</span>
                                    </div>

                                    <div class="hashtag-suggestions">
                                        <v-btn variant="text" :ripple="false"
                                            v-for="entry in hashtagSuggestions"
                                            :key="`suggestion-${entry.tag}`"
                                            class="hashtag-suggestion"
                                            type="button"
                                            @click="addHashtag(entry.tag)"
                                        >
                                            <span>{{ entry.tag }}</span>
                                            <small>{{ entry.count }}</small>
                                        </v-btn>
                                    </div>
                                </div>
                            </label>
                        </div>
                    </div>

                    <div class="content-section preview-editor-section">
                        <div class="section-title-row">
                            <strong>Target channels</strong>
                            <span>{{ selectedPlacements.length }} selected</span>
                        </div>

                        <div class="preview-editor">
                            <aside class="target-rail">
                                <template v-if="groupedChannels.length">
                                    <div
                                        v-for="group in groupedChannels"
                                        :key="group.network"
                                        class="target-group"
                                    >
                                        <span>{{ group.network }}</span>

                                        <v-btn variant="text" :ripple="false"
                                            v-for="channel in group.channels"
                                            :key="channel.id"
                                            class="target-channel"
                                            :class="{
                                                selected: isChannelSelected(channel.id),
                                                active: activePlacement?.channelId === channel.id,
                                            }"
                                            type="button"
                                            @click="toggleChannel(channel)"
                                        >
                                            <v-icon
                                                class="target-check"
                                                :icon="isChannelSelected(channel.id) ? mdiCheckboxMarked : mdiCheckboxBlankOutline"
                                            />
                                            <v-icon
                                                class="target-network"
                                                :icon="channelIcon(channel.network)"
                                            />
                                            <span>
                                                <strong>{{ channel.name }}</strong>
                                                <small>{{ channel.handle || channel.network }}</small>
                                            </span>
                                        </v-btn>
                                    </div>
                                </template>

                                <div
                                    v-else
                                    class="empty-note"
                                >
                                    Add workspace channels before choosing publication targets.
                                </div>
                            </aside>

                            <div class="preview-stage">
                                <div
                                    v-if="selectedPlacements.length"
                                    class="selected-preview-tabs"
                                >
                                    <v-btn variant="text" :ripple="false"
                                        v-for="placement in selectedPlacements"
                                        :key="placement.id"
                                        class="selected-preview-tab"
                                        :class="{ active: activePlacement?.id === placement.id }"
                                        type="button"
                                        @click="setActivePlacement(placement)"
                                    >
                                        <v-icon :icon="channelIcon(placement.network)" />
                                        <span>{{ placement.channelName || placement.network }}</span>
                                    </v-btn>
                                </div>

                                <article
                                    v-if="activePlacement"
                                    class="social-preview-card"
                                    :class="`is-${previewNetworkClass(activePlacement.network)}`"
                                >
                                    <div class="preview-topbar">
                                        <div class="preview-profile">
                                            <div class="preview-avatar">
                                                <v-icon :icon="channelIcon(activePlacement.network)" />
                                            </div>
                                            <div>
                                                <strong>{{ previewProfileName(activePlacement) }}</strong>
                                                <span>{{ previewHandle(activePlacement) }}</span>
                                            </div>
                                        </div>
                                        <v-btn variant="text" :ripple="false"
                                            class="preview-remove"
                                            type="button"
                                            :aria-label="`Remove ${previewProfileName(activePlacement)}`"
                                            @click="removePlacement(activePlacement.id)"
                                        >
                                            <v-icon :icon="mdiClose" />
                                        </v-btn>
                                    </div>

                                    <div
                                        v-if="previewNetworkClass(activePlacement.network) === 'youtube'"
                                        class="youtube-preview"
                                    >
                                        <div class="youtube-player">
                                            <v-icon :icon="mdiYoutube" />
                                        </div>
                                        <div class="youtube-meta">
                                            <strong>{{ form.title || 'Untitled video' }}</strong>
                                            <span>{{ previewProfileName(activePlacement) }}</span>
                                            <p>{{ sharedPreviewText }}</p>
                                        </div>
                                    </div>

                                    <div
                                        v-else-if="previewNetworkClass(activePlacement.network) === 'x'"
                                        class="x-preview"
                                    >
                                        <p>{{ sharedPreviewText }}</p>
                                        <div
                                            v-if="sharedPreviewTags.length"
                                            class="preview-tags"
                                        >
                                            <span
                                                v-for="tag in sharedPreviewTags"
                                                :key="`x-${tag}`"
                                            >
                                                {{ tag.startsWith('#') ? tag : `#${tag}` }}
                                            </span>
                                        </div>
                                        <div class="x-engagement">
                                            <span>Reply</span>
                                            <span>Repost</span>
                                            <span>Like</span>
                                            <span>Share</span>
                                        </div>
                                    </div>

                                    <div
                                        v-else
                                        class="feed-preview"
                                    >
                                        <div class="feed-media">
                                            <v-icon :icon="channelIcon(activePlacement.network)" />
                                        </div>
                                        <p>{{ sharedPreviewText }}</p>
                                        <div
                                            v-if="sharedPreviewTags.length"
                                            class="preview-tags"
                                        >
                                            <span
                                                v-for="tag in sharedPreviewTags"
                                                :key="`feed-${tag}`"
                                            >
                                                {{ tag.startsWith('#') ? tag : `#${tag}` }}
                                            </span>
                                        </div>
                                    </div>
                                </article>

                                <div
                                    v-else
                                    class="preview-empty-state"
                                >
                                    <strong>Select one or more channels</strong>
                                    <span>The shared content will preview here for every selected target.</span>
                                </div>
                            </div>
                        </div>
                    </div>
                    </main>
                </section>

                <aside class="panel side-panel">
                    <div class="panel-heading">
                        <strong>Production</strong>
                        <span v-if="!isCreateMode">{{ item?.currentRevisionLabel ?? 'Draft' }}</span>
                    </div>

                    <div
                        v-if="isCreateMode"
                        class="empty-note"
                    >
                        Save the content first to start comments, revisions, assets, and activity.
                    </div>

                    <template v-else>
                        <div class="tab-strip">
                            <v-btn variant="text" :ripple="false"
                                v-for="tab in productionTabs"
                                :key="tab.key"
                                class="tab-button"
                                :class="{ active: activeProductionTab === tab.key }"
                                type="button"
                                @click="activeProductionTab = tab.key"
                            >
                                {{ tab.label }}
                                <span>{{ tab.count }}</span>
                            </v-btn>
                        </div>

                        <template v-if="activeProductionTab === 'comments'">
                            <ContentCommentComposer
                                :members="workspaceMembers"
                                :is-posting="detailStore.actions.comment"
                                @submit-comment="submitComment"
                            />

                            <ContentCommentFeed
                                :comments="detailStore.comments"
                                :members="workspaceMembers"
                                :is-posting="detailStore.actions.comment"
                                @submit-comment="submitComment"
                            />
                        </template>

                        <template v-else-if="activeProductionTab === 'revisions'">
                            <div class="timeline-list">
                                <article
                                    v-for="revision in detailStore.revisions"
                                    :key="revision.id"
                                    class="timeline-row"
                                >
                                    <div class="timeline-row-header">
                                        <strong>{{ revision.revisionLabel }}</strong>
                                        <small>{{ formatDateTime(revision.createdAt) }}</small>
                                    </div>
                                    <span>{{ revision.title }}</span>
                                    <p v-if="revision.changeSummary">{{ revision.changeSummary }}</p>
                                    <small>{{ revision.publicationTargets }}</small>
                                </article>

                                <div
                                    v-if="!detailStore.revisions.length"
                                    class="empty-note"
                                >
                                    No revisions have been saved yet.
                                </div>
                            </div>
                        </template>

                        <template v-else-if="activeProductionTab === 'assets'">
                            <div class="panel-stack asset-form">
                                <v-select
                                    v-model="assetForm.assetType"
                                    :items="['Image', 'Video', 'Document', 'Other']"
                                    label="Type"
                                    variant="outlined"
                                    hide-details
                                />
                                <v-text-field
                                    v-model="assetForm.displayName"
                                    label="Name"
                                    placeholder="Final reel, cover image..."
                                    variant="outlined"
                                    hide-details
                                />
                                <v-text-field
                                    v-model="assetForm.googleDriveLink"
                                    class="field-wide"
                                    label="Google Drive link"
                                    type="url"
                                    placeholder="https://drive.google.com/..."
                                    variant="outlined"
                                    hide-details
                                />
                                <v-text-field
                                    v-model="assetForm.googleDriveFileId"
                                    label="File id"
                                    placeholder="Optional if link includes it"
                                    variant="outlined"
                                    hide-details
                                />
                                <v-text-field
                                    v-model="assetForm.previewUrl"
                                    label="Preview URL"
                                    type="url"
                                    variant="outlined"
                                    hide-details
                                />
                                <v-btn variant="text" :ripple="false"
                                    class="primary-button field-wide"
                                    :disabled="detailStore.actions.asset"
                                    @click="linkGoogleDriveAsset"
                                >
                                    {{ detailStore.actions.asset ? 'Linking...' : 'Link asset' }}
                                </v-btn>
                            </div>

                            <div class="timeline-list">
                                <article
                                    v-for="asset in detailStore.assets"
                                    :key="asset.id"
                                    class="asset-card"
                                >
                                    <div class="timeline-row-header">
                                        <div>
                                            <strong>{{ asset.displayName }}</strong>
                                            <span>{{ asset.assetType }} · {{ asset.sourceType }}</span>
                                        </div>
                                        <span class="revision-pill">v{{ asset.currentRevisionNumber }}</span>
                                    </div>

                                    <a
                                        class="asset-link"
                                        :href="asset.googleDriveLink"
                                        target="_blank"
                                        rel="noreferrer"
                                    >
                                        Open source
                                    </a>

                                    <div class="asset-revisions">
                                        <div
                                            v-for="revision in asset.revisions"
                                            :key="revision.id"
                                            class="asset-revision-row"
                                        >
                                            <span>v{{ revision.revisionNumber }}</span>
                                            <small>{{ formatDateTime(revision.createdAt) }}</small>
                                            <p v-if="revision.notes">{{ revision.notes }}</p>
                                        </div>
                                    </div>

                                    <div class="panel-stack compact-form">
                                        <v-text-field
                                            v-model="assetRevisionForm(asset.id).sourceReference"
                                            class="field-wide"
                                            label="New revision reference"
                                            type="url"
                                            placeholder="Updated Drive link or production reference"
                                            variant="outlined"
                                            hide-details
                                        />
                                        <v-text-field
                                            v-model="assetRevisionForm(asset.id).notes"
                                            class="field-wide"
                                            label="Notes"
                                            placeholder="What changed?"
                                            variant="outlined"
                                            hide-details
                                        />
                                        <v-btn variant="text" :ripple="false"
                                            class="secondary-button"
                                            :disabled="detailStore.actions.assetRevision"
                                            @click="addAssetRevision(asset)"
                                        >
                                            {{ detailStore.actions.assetRevision ? 'Adding...' : 'Add revision' }}
                                        </v-btn>
                                    </div>
                                </article>

                                <div
                                    v-if="!detailStore.assets.length"
                                    class="empty-note"
                                >
                                    No production assets have been linked yet.
                                </div>
                            </div>
                        </template>

                        <template v-else>
                            <div class="timeline-list">
                                <article
                                    v-for="entry in detailStore.activity"
                                    :key="entry.id"
                                    class="timeline-row"
                                >
                                    <div class="timeline-row-header">
                                        <strong>{{ entry.eventType }}</strong>
                                        <small>{{ formatDateTime(entry.createdAt) }}</small>
                                    </div>
                                    <span>{{ entry.summary }}</span>
                                </article>

                                <div
                                    v-if="!detailStore.activity.length"
                                    class="empty-note"
                                >
                                    No activity has been recorded yet.
                                </div>
                            </div>
                        </template>
                    </template>
                </aside>
            </div>

            <div
                v-if="activeCalendarEvent"
                class="calendar-event-popover"
                role="dialog"
                aria-modal="true"
            >
                <div class="calendar-event-card">
                    <div class="calendar-event-header">
                        <div>
                            <span>{{ activeCalendarEvent.source?.displayTitle ?? t('contentItems.calendar.importedEvent') }}</span>
                            <strong>{{ activeCalendarEvent.title }}</strong>
                        </div>
                        <v-btn variant="text" :ripple="false"
                            class="link-button"
                            type="button"
                            @click="closeCalendarEvent"
                        >
                            {{ t('close') }}
                        </v-btn>
                    </div>

                    <p>{{ formatCalendarDate(activeCalendarEvent.startDate) }}</p>
                    <p v-if="activeCalendarEvent.description">{{ activeCalendarEvent.description }}</p>
                    <p v-if="activeCalendarEvent.location">{{ activeCalendarEvent.location }}</p>

                    <div class="calendar-event-actions">
                        <v-btn variant="text" :ripple="false"
                            class="secondary-button"
                            type="button"
                            @click="navigateToCalendarDay(activeCalendarEvent)"
                        >
                            {{ t('contentItems.dateContext.viewDay') }}
                        </v-btn>
                    </div>
                </div>
            </div>
        </template>
    </section>
</template>

<style scoped>
@reference "@/assets/main.css";
    .editor-shell {
        @apply mx-auto flex w-full max-w-[110rem] flex-col gap-5 px-5 py-8 md:px-8;
    }

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

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

    .editor-header {
        @apply flex flex-col gap-4 rounded-[1.75rem] border p-6 lg:flex-row lg:items-start lg:justify-between;
        background: rgba(255, 255, 255, 0.92);
        border-color: var(--app-border-subtle);
    }

    .eyebrow {
        @apply text-xs font-bold uppercase tracking-[0.24em];
        color: var(--app-color-on-tertiary);
    }

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

    .editor-header p,
    .panel-heading span,
    .timeline-row span,
    .timeline-row small,
    .empty-note,
    .placement-header span,
    .section-title-row span {
        @apply text-sm leading-6;
        color: var(--app-text-muted);
    }

    .header-actions,
    .status-badges {
        @apply flex flex-wrap items-center gap-3;
    }

    .meta-chip {
        @apply rounded-full px-4 py-2 text-xs font-bold uppercase tracking-[0.16em];
        background: var(--app-border-subtle);
        color: var(--app-color-on-surface);
    }

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

    .back-button {
        @apply w-fit border;
        background: rgba(255, 255, 255, 0.88);
        border-color: var(--app-border-subtle);
        color: var(--app-color-on-surface);
    }

    .back-button:hover {
        background: var(--app-color-on-surface);
        color: var(--app-color-on-primary);
    }

    .primary-button {
        background: var(--app-color-on-surface);
        color: var(--app-color-on-primary);
    }

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

    .editor-grid {
        @apply grid gap-4 xl:grid-cols-[minmax(0,1fr)_22rem];
    }

    .work-panel {
        @apply grid min-w-0 grid-cols-[2.75rem_minmax(0,1fr)] items-start gap-4 rounded-[1.75rem] border p-5;
        background: rgba(255, 255, 255, 0.9);
        border-color: var(--app-border-subtle);
    }

    .panel {
        @apply flex min-h-0 flex-col gap-5 rounded-[1.75rem] border p-5;
        background: rgba(255, 255, 255, 0.9);
        border-color: var(--app-border-subtle);
    }

    .side-panel {
        @apply xl:sticky xl:top-28 xl:max-h-[calc(100vh-9rem)] xl:overflow-y-auto;
    }

    .content-panel {
        @apply flex min-h-0 flex-col gap-6;
    }

    .panel-heading,
    .section-title-row,
    .placement-header {
        @apply flex items-start justify-between gap-3;
    }

    .panel-heading strong,
    .section-title-row strong,
    .placement-header strong,
    .timeline-row strong {
        color: var(--app-color-on-surface);
    }

    .panel-stack,
    .content-section,
    .placement-list,
    .media-section,
    .media-list,
    .card-stack,
    .timeline-list {
        @apply flex flex-col gap-4;
    }

    .form-grid {
        @apply grid gap-4 md:grid-cols-2;
    }

    .compact-grid {
        @apply md:grid-cols-2;
    }

    .field {
        @apply flex flex-col gap-2;
    }

    .field-wide {
        @apply md:col-span-2;
    }

    .field span {
        @apply text-sm font-semibold;
        color: var(--app-color-on-surface);
    }

    .field input,
    .field select,
    .field textarea {
        @apply rounded-[1rem] border px-4 py-3 text-sm;
        background: var(--app-color-surface);
        border-color: var(--app-border-subtle);
        color: var(--app-color-on-surface);
        outline: none;
    }

    .field textarea {
        min-height: 7rem;
        resize: vertical;
    }

    .date-context {
        @apply flex flex-col gap-3 rounded-[1rem] border p-3;
        background: rgba(15, 118, 110, 0.04);
        border-color: rgba(15, 118, 110, 0.14);
    }

    .date-context-days {
        @apply grid grid-cols-2 gap-2 sm:grid-cols-4 lg:grid-cols-7;
    }

    .date-context-day {
        @apply flex min-h-14 flex-col items-start justify-between rounded-[0.875rem] border px-3 py-2 text-left transition;
        background: rgba(255, 253, 248, 0.9);
        border-color: var(--app-border-subtle);
        color: var(--app-text-muted);
    }

    .date-context-day span {
        @apply text-xs font-bold uppercase tracking-[0.12em];
    }

    .date-context-day strong {
        @apply h-5 min-w-5 rounded-full px-1.5 text-center text-xs leading-5;
        background: var(--app-border-subtle);
        color: var(--app-color-on-surface);
    }

    .date-context-day.marked {
        border-color: rgba(15, 118, 110, 0.32);
        color: var(--app-color-on-tertiary);
    }

    .date-context-day.marked strong,
    .date-context-day.active strong {
        background: var(--app-color-on-tertiary);
        color: var(--app-color-on-primary);
    }

    .date-context-day.active {
        background: var(--app-color-on-surface);
        border-color: var(--app-color-on-surface);
        color: var(--app-color-on-primary);
    }

    .date-context-panel {
        @apply flex flex-wrap gap-2;
    }

    .calendar-context-pill {
        @apply rounded-full border px-3 py-1.5 text-xs font-bold transition;
        background: color-mix(in srgb, var(--calendar-color) 12%, white);
        border-color: color-mix(in srgb, var(--calendar-color) 34%, white);
        color: var(--app-color-on-surface);
    }

    .calendar-context-pill:hover {
        background: var(--calendar-color);
        color: var(--app-color-on-primary);
    }

    .date-context-empty {
        @apply text-sm leading-6;
        color: var(--app-text-muted);
    }

    .hashtags-input-shell {
        @apply flex min-h-14 flex-wrap items-center gap-2 rounded-[1rem] border px-4 py-3;
        background: var(--app-color-surface);
        border-color: var(--app-border-subtle);
    }

    .hashtags-editor {
        @apply flex flex-wrap gap-2;
    }

    .hashtags-inline-input {
        @apply min-w-[10rem] flex-1 border-0 bg-transparent p-0 text-sm;
        color: var(--app-color-on-surface);
        outline: none;
    }

    .hashtags-inline-input::placeholder {
        color: var(--app-text-muted);
    }

    .hashtag-chip {
        @apply font-bold;
    }

    .hashtag-feed {
        @apply flex flex-col gap-2 rounded-[1rem] border p-3;
        background: rgba(15, 118, 110, 0.04);
        border-color: rgba(15, 118, 110, 0.12);
    }

    .hashtag-feed-heading {
        @apply flex items-center justify-between gap-3;
    }

    .hashtag-feed-heading strong {
        @apply text-xs font-bold uppercase tracking-[0.16em];
        color: var(--app-color-on-surface);
    }

    .hashtag-feed-heading span {
        @apply text-xs font-semibold;
        color: var(--app-text-muted);
    }

    .hashtag-suggestions {
        @apply flex flex-wrap gap-2;
    }

    .hashtag-suggestion {
        @apply inline-flex min-h-8 items-center gap-2 rounded-full border px-3 py-1 text-xs font-bold;
        background: rgba(15, 118, 110, 0.06);
        border-color: rgba(15, 118, 110, 0.14);
        color: var(--app-color-on-tertiary);
    }

    .hashtag-suggestion small {
        @apply rounded-full px-1.5 py-0.5 text-[0.65rem] font-black leading-none;
        background: rgba(15, 118, 110, 0.12);
        color: var(--app-color-on-tertiary);
    }

    .hashtag-suggestion:hover {
        background: var(--app-color-on-tertiary);
        color: var(--app-color-on-primary);
    }

    .hashtag-suggestion:hover small {
        background: rgba(255, 255, 255, 0.2);
        color: var(--app-color-on-primary);
    }

    .preview-editor-section {
        @apply rounded-[1.25rem] border p-4;
        background: #f8fafc;
        border-color: var(--app-border-subtle);
    }

    .preview-editor {
        @apply grid gap-4 lg:grid-cols-[18rem_minmax(0,1fr)];
    }

    .target-rail {
        @apply flex min-w-0 flex-col gap-4 rounded-[1rem] border p-3;
        background: var(--app-color-on-primary);
        border-color: var(--app-border-subtle);
    }

    .target-group {
        @apply flex flex-col gap-2;
    }

    .target-group > span {
        @apply px-2 text-xs font-bold uppercase tracking-[0.16em];
        color: var(--app-text-muted);
    }

    .target-channel {
        @apply grid min-h-16 w-full grid-cols-[1.25rem_2rem_minmax(0,1fr)] items-center gap-3 rounded-[0.875rem] border px-3 py-2 text-left transition;
        background: var(--app-control-subtle);
        border-color: transparent;
        color: var(--app-color-on-surface);
    }

    .target-channel:hover,
    .target-channel.selected {
        background: rgba(15, 118, 110, 0.08);
        border-color: rgba(15, 118, 110, 0.2);
    }

    .target-channel.active {
        background: var(--app-color-on-surface);
        color: var(--app-color-on-primary);
    }

    .target-check {
        @apply text-lg;
        color: var(--app-color-on-tertiary);
    }

    .target-channel.active .target-check {
        color: var(--app-color-on-primary);
    }

    .target-network,
    .preview-avatar {
        @apply grid h-8 w-8 place-items-center rounded-full;
        background: rgba(15, 118, 110, 0.12);
        color: var(--app-color-on-tertiary);
    }

    .target-channel.active .target-network {
        background: rgba(255, 255, 255, 0.18);
        color: var(--app-color-on-primary);
    }

    .target-channel span {
        @apply flex min-w-0 flex-col gap-0.5;
    }

    .target-channel strong,
    .target-channel small {
        @apply block truncate;
    }

    .target-channel strong {
        @apply text-sm font-bold;
    }

    .target-channel small {
        @apply text-xs;
        color: var(--app-text-muted);
    }

    .target-channel.active small {
        color: rgba(255, 255, 255, 0.72);
    }

    .preview-stage {
        @apply flex min-w-0 flex-col gap-3;
    }

    .selected-preview-tabs {
        @apply flex gap-2 overflow-x-auto pb-1;
    }

    .selected-preview-tab {
        @apply inline-flex min-h-10 shrink-0 items-center gap-2 rounded-full border px-3 py-2 text-sm font-bold transition;
        background: var(--app-color-on-primary);
        border-color: var(--app-border-subtle);
        color: var(--app-color-on-surface);
    }

    .selected-preview-tab.active {
        background: var(--app-color-on-surface);
        border-color: var(--app-color-on-surface);
        color: var(--app-color-on-primary);
    }

    .social-preview-card {
        @apply flex min-h-[28rem] flex-col gap-4 rounded-[1.25rem] border p-4 shadow-sm;
        background: var(--app-color-on-primary);
        border-color: var(--app-border-subtle);
    }

    .preview-topbar,
    .preview-profile {
        @apply flex items-center gap-3;
    }

    .preview-topbar {
        @apply justify-between;
    }

    .preview-profile div:last-child {
        @apply flex min-w-0 flex-col;
    }

    .preview-profile strong {
        @apply truncate text-sm font-black;
        color: var(--app-color-on-surface);
    }

    .preview-profile span,
    .youtube-meta span,
    .x-engagement span {
        @apply text-xs;
        color: var(--app-text-muted);
    }

    .preview-remove {
        @apply grid h-9 w-9 place-items-center rounded-full p-0;
        color: var(--app-text-muted);
    }

    .youtube-preview,
    .feed-preview,
    .x-preview {
        @apply flex flex-1 flex-col gap-4;
    }

    .youtube-player {
        @apply grid aspect-video w-full place-items-center rounded-[1rem];
        background: #111827;
        color: #ef4444;
    }

    .youtube-player :deep(.v-icon) {
        @apply text-6xl;
    }

    .youtube-meta {
        @apply flex flex-col gap-2;
    }

    .youtube-meta strong {
        @apply text-xl font-black;
        color: var(--app-color-on-surface);
    }

    .youtube-meta p,
    .x-preview p,
    .feed-preview p {
        @apply whitespace-pre-line text-sm leading-6;
        color: var(--app-color-on-surface);
    }

    .x-preview {
        @apply rounded-[1rem] border p-4;
        border-color: var(--app-border-subtle);
    }

    .x-preview p {
        @apply text-lg leading-8;
    }

    .x-engagement {
        @apply mt-auto grid grid-cols-4 gap-2 border-t pt-3 text-center;
        border-color: var(--app-border-subtle);
    }

    .feed-media {
        @apply grid aspect-[4/5] w-full place-items-center rounded-[1rem];
        background: linear-gradient(135deg, #0f766e, #f97316);
        color: white;
    }

    .feed-media :deep(.v-icon) {
        @apply text-5xl;
    }

    .preview-tags {
        @apply flex flex-wrap gap-2;
    }

    .preview-tags span {
        @apply rounded-full px-3 py-1 text-xs font-bold;
        background: rgba(15, 118, 110, 0.1);
        color: var(--app-color-on-tertiary);
    }

    .preview-empty-state {
        @apply grid min-h-[24rem] place-items-center rounded-[1.25rem] border p-8 text-center;
        background: var(--app-color-on-primary);
        border-color: var(--app-border-subtle);
    }

    .preview-empty-state strong {
        @apply text-lg font-black;
        color: var(--app-color-on-surface);
    }

    .preview-empty-state span {
        @apply mt-2 block max-w-sm text-sm leading-6;
        color: var(--app-text-muted);
    }

    .network-pill {
        @apply rounded-full border px-4 py-2 text-xs font-bold uppercase tracking-[0.16em];
        background: var(--app-control-subtle);
        border-color: var(--app-border-subtle);
        color: var(--app-color-on-surface);
    }

    .channel-suggestions {
        @apply flex flex-wrap gap-2;
    }

    .placement-card,
    .media-card {
        @apply rounded-[1.25rem] border p-4;
        background: var(--app-color-on-primary);
        border-color: var(--app-border-subtle);
    }

    .identity-row {
        @apply flex items-center gap-3;
    }

    .identity-row.align-start {
        @apply items-start;
    }

    .timeline-row {
        @apply flex flex-col gap-3 rounded-[1rem] border p-4;
        background: #f8fafc;
        border-color: var(--app-border-subtle);
    }

    .timeline-row-header {
        @apply flex items-start justify-between gap-3;
    }

    .timeline-row p,
    .asset-revision-row p {
        @apply text-sm leading-6;
        color: var(--app-color-on-surface);
    }

    .timeline-actions {
        @apply flex items-center justify-between gap-3;
    }

    .timeline-list.compact .timeline-row {
        @apply p-3;
    }

    .tab-strip {
        @apply grid grid-cols-2 gap-2;
    }

    .tab-button {
        @apply flex items-center justify-between gap-2 rounded-[1rem] border px-3 py-2 text-sm font-bold transition;
        background: var(--app-control-subtle);
        border-color: var(--app-border-subtle);
        color: var(--app-color-on-surface);
    }

    .tab-button.active {
        background: var(--app-color-on-surface);
        color: var(--app-color-on-primary);
    }

    .tab-button span {
        @apply rounded-full px-2 py-0.5 text-xs;
        background: rgba(255, 255, 255, 0.22);
    }

    .asset-form {
        @apply grid gap-4 sm:grid-cols-2;
    }

    .asset-card {
        @apply flex flex-col gap-4 rounded-[1rem] border p-4;
        background: var(--app-color-on-primary);
        border-color: var(--app-border-subtle);
    }

    .asset-card .timeline-row-header span,
    .asset-revision-row small {
        @apply text-sm leading-6;
        color: var(--app-text-muted);
    }

    .asset-link {
        @apply w-fit text-sm font-semibold;
        color: var(--app-color-on-tertiary);
    }

    .revision-pill {
        @apply rounded-full px-3 py-1 text-xs font-bold;
        background: rgba(15, 118, 110, 0.12);
        color: var(--app-color-on-tertiary);
    }

    .asset-revisions {
        @apply flex flex-col gap-2;
    }

    .asset-revision-row {
        @apply rounded-[0.875rem] border px-3 py-2;
        background: rgba(255, 255, 255, 0.7);
        border-color: var(--app-border-subtle);
    }

    .asset-revision-row span {
        @apply mr-2 text-sm font-bold;
        color: var(--app-color-on-surface);
    }

    .compact-form {
        @apply gap-3;
    }

    .link-button {
        @apply text-sm font-semibold;
        color: var(--app-color-on-tertiary);
    }

    .calendar-event-popover {
        @apply fixed inset-0 z-50 flex items-center justify-center bg-slate-950/35 p-4;
    }

    .calendar-event-card {
        @apply flex w-full max-w-md flex-col gap-4 rounded-[1.25rem] border p-5 shadow-2xl;
        background: var(--app-color-surface);
        border-color: var(--app-border-subtle);
    }

    .calendar-event-header {
        @apply flex items-start justify-between gap-4;
    }

    .calendar-event-header div {
        @apply flex flex-col gap-1;
    }

    .calendar-event-header span,
    .calendar-event-card p {
        @apply text-sm leading-6;
        color: var(--app-text-muted);
    }

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

    .calendar-event-actions {
        @apply flex justify-end;
    }

    @media (max-width: 1279px) {
        .side-panel {
            position: static;
            max-height: none;
            overflow: visible;
        }
    }
</style>
