<template>
    <modal-form
        ref="$modal"
        :loading="loading"
        :title="langTitle"
        :error="error"
        :disable-save-button="v$.$invalid"
        @submit="doSubmit"
        @hidden="clearContents"
    >
        <type-select
            v-if="!type"
            :webhook-types="webhookTypes"
            @select="setType"
        />
        <b-tabs
            v-else
            lazy
            content-class="mt-3"
            pills
        >
            <b-tab active>
                <template #title>
                    {{ $gettext('Basic Info') }}
                </template>

                <basic-info
                    :trigger-options="triggerOptions"
                    :form="v$"
                />
            </b-tab>
            <b-tab :title="typeTitle">
                <component
                    :is="formComponent"
                    :now-playing-url="nowPlayingUrl"
                    :form="v$"
                />
            </b-tab>
        </b-tabs>
    </modal-form>
</template>

<script setup>
import {required} from '@vuelidate/validators';
import TypeSelect from "./Form/TypeSelect";
import BasicInfo from "./Form/BasicInfo";
import {get, map} from "lodash";
import Generic from "./Form/Generic";
import Email from "./Form/Email";
import Tunein from "./Form/Tunein";
import Discord from "./Form/Discord";
import Telegram from "./Form/Telegram";
import Twitter from "./Form/Twitter";
import GoogleAnalyticsV3 from "./Form/GoogleAnalyticsV3";
import GoogleAnalyticsV4 from "./Form/GoogleAnalyticsV4";
import MatomoAnalytics from "./Form/MatomoAnalytics";
import Mastodon from "./Form/Mastodon";
import {baseEditModalProps, useBaseEditModal} from "~/functions/useBaseEditModal";
import {computed, ref} from "vue";
import {useTranslate} from "~/vendor/gettext";
import ModalForm from "~/components/Common/ModalForm.vue";

const props = defineProps({
    ...baseEditModalProps,
    nowPlayingUrl: {
        type: String,
        required: true
    },
    webhookTypes: {
        type: Object,
        required: true
    },
    triggerTitles: {
        type: Object,
        required: true
    },
    triggerDescriptions: {
        type: Object,
        required: true
    }
});

const emit = defineEmits(['relist']);

const type = ref(null);

const $modal = ref(); // Template Ref

const {$gettext} = useTranslate();

const langPoweredByAzuraCast = $gettext('Powered by AzuraCast');

const langDiscordDefaultContent = $gettext(
    'Now playing on %{ station }:',
    {'station': '{{ station.name }}'}
);

const langTelegramDefaultContent = $gettext(
    'Now playing on %{ station }: %{ title } by %{ artist }! Tune in now.',
    {
        station: '{{ station.name }}',
        title: '{{ now_playing.song.title }}',
        artist: '{{ now_playing.song.artist }}'
    }
);

const langTwitterDefaultMessage = $gettext(
    'Now playing on %{ station }: %{ title } by %{ artist }! Tune in now: %{ url }',
    {
        station: '{{ station.name }}',
        title: '{{ now_playing.song.title }}',
        artist: '{{ now_playing.song.artist }}',
        url: '{{ station.public_player_url }}'
    }
);

const langTwitterSongChangedLiveMessage = $gettext(
    'Now playing on %{ station }: %{ title } by %{ artist } with your host, %{ dj }! Tune in now: %{ url }',
    {
        station: '{{ station.name }}',
        title: '{{ now_playing.song.title }}',
        artist: '{{ now_playing.song.artist }}',
        dj: '{{ live.streamer_name }}',
        url: '{{ station.public_player_url }}'
    }
);

const langTwitterDjOnMessage = $gettext(
    '%{ dj } is now live on %{ station }! Tune in now: %{ url }',
    {
        dj: '{{ live.streamer_name }}',
        station: '{{ station.name }}',
        url: '{{ station.public_player_url }}'
    }
);

const langTwitterDjOffMessage = $gettext(
    'Thanks for listening to %{ station }!',
    {
        station: '{{ station.name }}',
    }
);

const langTwitterStationOfflineMessage = $gettext(
    '%{ station } is going offline for now.',
    {
        station: '{{ station.name }}'
    }
);

const langTwitterStationOnlineMessage = $gettext(
    '%{ station } is back online! Tune in now: %{ url }',
    {
        station: '{{ station.name }}',
        url: '{{ station.public_player_url }}'
    }
);

const webhookConfig = {
    'generic': {
        component: Generic,
        validations: {
            webhook_url: {required},
            basic_auth_username: {},
            basic_auth_password: {},
            timeout: {},
        },
        defaultConfig: {
            webhook_url: '',
            basic_auth_username: '',
            basic_auth_password: '',
            timeout: '5',
        }
    },
    'email': {
        component: Email,
        validations: {
            to: {required},
            subject: {required},
            message: {required}
        },
        defaultConfig: {
            to: '',
            subject: '',
            message: ''
        }
    },
    'tunein': {
        component: Tunein,
        validations: {
            station_id: {required},
            partner_id: {required},
            partner_key: {required},
        },
        defaultConfig: {
            station_id: '',
            partner_id: '',
            partner_key: ''
        }
    },
    'discord': {
        component: Discord,
        validations: {
            webhook_url: {required},
            content: {},
            title: {},
            description: {},
            url: {},
            author: {},
            thumbnail: {},
            footer: {},
        },
        defaultConfig: {
            webhook_url: '',
            content: langDiscordDefaultContent,
            title: '{{ now_playing.song.title }}',
            description: '{{ now_playing.song.artist }}',
            url: '{{ station.listen_url }}',
            author: '{{ live.streamer_name }}',
            thumbnail: '{{ now_playing.song.art }}',
            footer: langPoweredByAzuraCast,
        }
    },
    'telegram': {
        component: Telegram,
        validations: {
            bot_token: {required},
            chat_id: {required},
            api: {},
            text: {required},
            parse_mode: {required}
        },
        defaultConfig: {
            bot_token: '',
            chat_id: '',
            api: '',
            text: langTelegramDefaultContent,
            parse_mode: 'Markdown'
        }
    },
    'twitter': {
        component: Twitter,
        validations: {
            consumer_key: {required},
            consumer_secret: {required},
            token: {required},
            token_secret: {required},
            rate_limit: {},
            message: {},
            message_song_changed_live: {},
            message_live_connect: {},
            message_live_disconnect: {},
            message_station_offline: {},
            message_station_online: {}
        },
        defaultConfig: {
            consumer_key: '',
            consumer_secret: '',
            token: '',
            token_secret: '',
            rate_limit: 0,
            message: langTwitterDefaultMessage,
            message_song_changed_live: langTwitterSongChangedLiveMessage,
            message_live_connect: langTwitterDjOnMessage,
            message_live_disconnect: langTwitterDjOffMessage,
            message_station_offline: langTwitterStationOfflineMessage,
            message_station_online: langTwitterStationOnlineMessage
        }
    },
    'mastodon': {
        component: Mastodon,
        validations: {
            instance_url: {required},
            access_token: {required},
            rate_limit: {},
            visibility: {required},
            message: {},
            message_song_changed_live: {},
            message_live_connect: {},
            message_live_disconnect: {},
            message_station_offline: {},
            message_station_online: {}
        },
        defaultConfig: {
            instance_url: '',
            access_token: '',
            rate_limit: 0,
            visibility: 'public',
            message: langTwitterDefaultMessage,
            message_song_changed_live: langTwitterSongChangedLiveMessage,
            message_live_connect: langTwitterDjOnMessage,
            message_live_disconnect: langTwitterDjOffMessage,
            message_station_offline: langTwitterStationOfflineMessage,
            message_station_online: langTwitterStationOnlineMessage
        }
    },
    'google_analytics': {
        component: GoogleAnalyticsV3,
        validations: {
            tracking_id: {required}
        },
        defaultConfig: {
            tracking_id: ''
        }
    },
    'google_analytics_v4': {
        component: GoogleAnalyticsV4,
        validations: {
            api_secret: {required},
            measurement_id: {required}
        },
        defaultConfig: {
            api_secret: '',
            measurement_id: ''
        }
    },
    'matomo_analytics': {
        component: MatomoAnalytics,
        validations: {
            matomo_url: {required},
            site_id: {required},
            token: {},
        },
        defaultConfig: {
            matomo_url: '',
            site_id: '',
            token: ''
        }
    }
};

const triggerOptions = computed(() => {
    if (!type.value) {
        return [];
    }

    let webhookKeys = get(props.webhookTypes, [type.value, 'triggers'], []);
    return map(webhookKeys, (key) => {
        return {
            html:
                '<h6 class="font-weight-bold mb-0">' + props.triggerTitles[key] + '</h6>'
                + '<p class="card-text small">' + props.triggerDescriptions[key] + '</p>',
            value: key
        };
    });
});

const typeTitle = computed(() => {
    return get(props.webhookTypes, [type.value, 'name'], '');
});

const formComponent = computed(() => {
    return get(webhookConfig, [type.value, 'component'], Generic);
});

const {
    loading,
    error,
    isEditMode,
    v$,
    resetForm,
    clearContents: originalClearContents,
    create,
    edit,
    doSubmit,
    close
} = useBaseEditModal(
    props,
    emit,
    $modal,
    () => computed(() => {
        let validations = {
            name: {required},
            triggers: {},
            config: {}
        };

        const triggerOptionsValue = triggerOptions.value;
        if (triggerOptionsValue.length > 0) {
            validations.triggers = {required};
        }

        if (type.value !== null) {
            validations.config = get(
                webhookConfig,
                [type.value, 'validations'],
                {}
            );
        }

        return validations;
    }),
    () => computed(() => {
        let newForm = {
            name: null,
            triggers: [],
            config: {}
        };

        if (type.value !== null) {
            newForm.config = get(
                webhookConfig,
                [type.value, 'defaultConfig'],
                {}
            );
        }

        return newForm;
    }),
    {
        populateForm: (data, formRef) => {
            type.value = data.type;
            formRef.value = {
                name: data.name,
                triggers: data.triggers,
                config: data.config
            };
        },
        getSubmittableFormData(formRef, isEditModeRef) {
            let formData = formRef.value;
            if (!isEditModeRef.value) {
                formData.type = type.value;
            }
            return formData;
        },
    }
);

const langTitle = computed(() => {
    return isEditMode.value
        ? $gettext('Edit Web Hook')
        : $gettext('Add Web Hook');
});

const clearContents = () => {
    type.value = null;
    originalClearContents();
};

const setType = (newType) => {
    type.value = newType;
    resetForm();
};

defineExpose({
    create,
    edit,
    close
});
</script>
