@extends('layouts.app')

@section('content')
<div class="container app-content pt-3">
    <h1 class="h3 mb-4" v-if="!progress">Exports</h1>
    <h1 class="h3 mb-4" v-if="progress">Export Process</h1>

    <div class="progress" v-if="progress">
        <div
            class="progress-bar bg-success progress-bar-striped progress-bar-animated"
            role="progressbar"
            :style="{width: ((exports.index_page/exports.pages.length)*100)+'%'}"
            aria-valuemin="0"
            aria-valuemax="100">
            <span v-text="Math.round( ( exports.index_page / exports.pages.length ) * 100 ) + '%'"></span>
        </div>
    </div>

    <transition name="fade">
        <form v-on:submit.prevent="exportProgress" v-if="!progress">
            <div class="card mb-3">
                <div class="card-body">
                    <div class="form-row">
                        <div class="col-md-6 mb-3">
                            <label>Export To</label>
                            <select class="form-control" v-model="formData.exportTo">
                                <option value="blogspot">Blogspot</option>
                                <option value="wordpress">Wordpress</option>
                            </select>
                        </div>
                        <div class="col-md-6 mb-3">
                            <label>Type</label>
                            <select class="form-control" v-model.lazy="formData.type" @change="changeType">
                                <option value="movie">Movie</option>
                                <option value="tv">Tv</option>
                            </select>
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Genre</label>
                            <select class="form-control" v-model="formData.genre">
                                <option value="">All</option>
                                <option v-for="(genre, index) in genre_lists" :key="index" :value="genre.id" v-text="genre.name"></option>
                            </select>
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Language</label>
                            <select class="form-control" v-model="formData.language">
                                <option v-for="(lang, index) in language_lists" :key="index" :value="lang.iso_639_1" v-text="lang.english_name"></option>
                            </select>
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Sort By</label>
                            <select class="form-control" v-model="formData.sort_by">
                                <option value="popularity.asc">Popularity Asc</option>
                                <option value="popularity.desc">Popularity Desc</option>
                                <option value="release_date.asc">Release Date Asc</option>
                                <option value="release_date.desc">Release Date Desc</option>
                                <option value="revenue.asc">Revenue Asc</option>
                                <option value="revenue.desc">Revenue Desc</option>
                                <option value="primary_release_date.asc">Primary Release Date Asc</option>
                                <option value="primary_release_date.desc">Primary Release Date Desc</option>
                                <option value="original_title.asc">Original Title Asc</option>
                                <option value="original_title.desc">Original Title Desc</option>
                                <option value="vote_average.asc">Vote Average Asc</option>
                                <option value="vote_average.desc">Vote Average Desc</option>
                                <option value="vote_count.asc">Vote Count Asc</option>
                                <option value="vote_count.desc">Vote Count Desc</option>
                            </select>
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Year</label>
                            <select class="form-control" v-model.number="formData.year">
                                <option v-for="(year, index) in year_lists" :key="index" :value="year" v-text="year"></option>
                            </select>
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Start Page</label>
                            <input type="number" class="form-control" v-model.number="formData.startPage" min="1" :max="max_pages">
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Max Page</label>
                            <input type="number" class="form-control" v-model.number="formData.finishPage" min="1" :max="max_pages">
                        </div>
                    </div>

                    <button v-if="!is_prepare" type="button" class="btn btn-outline-danger" v-on:click.prevent="getPrepare">Get a maximum of pages?</button>

                    <button v-if="is_prepare" class="btn btn-outline-danger" type="button" disabled>
                        <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                        <span class="sr-only">Loading...</span>
                    </button>

                    <span v-if="prepare.length !== 0" class="ml-3">Maximum Number of Pages = <span class="font-weight-bold"  v-text="prepare.total_pages"></span></span>
                </div>
            </div>

            <div class="card">
                <div class="card-body">
                    <div class="form-row">
                        <div class="col-md-4 mb-3">
                            <label>Templates</label>
                            <select class="form-control" v-model="formData.template" required>
                                <option value="">Select template...</option>
                                <option v-for="(template, index) in template_lists" :key="index" :value="template.id" v-text="template.name"></option>
                            </select>
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Publish Start Date</label>
                            <vuejs-datepicker
                                :required="true"
                                placeholder="Select Date"
                                v-model="formData.start_date"
                                :bootstrap-styling="true">
                            </vuejs-datepicker>
                        </div>
                        <div class="col-md-4 mb-3">
                            <label>Publish End Date</label>
                            <vuejs-datepicker
                                :required="true"
                                placeholder="Select Date"
                                v-model="formData.end_date"
                                :bootstrap-styling="true">
                            </vuejs-datepicker>
                        </div>
                    </div>
                </div>
                <div class="card-footer bg-white">
                    <button type="submit" class="btn btn-primary btn-block btn-lg"><i class="fa fa-truck-monster mr-2"></i> Export</button>
                </div>
            </div>
        </form>
    </transition>
</div>
@endsection

@section('footer')
    <script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="//cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="//unpkg.com/vuejs-datepicker"></script>
    <script src="//cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
    <script>
        // axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

        let app = new Vue({
            el: '#app',
            components: {
                vuejsDatepicker
            },
            data: {
                api_key: '{{ get_tmdb_key() }}',
                is_prepare: false,
                prepare: [],
                progress: false,
                max_pages: 500,
                genre_lists : [],
                language_lists : [],
                template_lists : [],
                year_lists : [],
                formData: {
                    exportTo: 'blogspot',
                    type: 'movie',
                    year: 2020,
                    genre: '',
                    sort_by: 'popularity.desc',
                    startPage: 1,
                    finishPage: 2,
                    language: 'en',
                    template: '',
                    start_date: '',
                    end_date: '',
                },
                exports: {
                    index_page: 0,
                    success: 0,
                    failed: 0,
                    pages: [],
                    total_page: 0,
                },
            },
            mounted() {
                this.fetchGenreMovieLists()
                this.fetchGenreTvLists()
                this.fetchLanguageLists()
                this.fetchTemplateLists('movie')
                this.fetchYearLists()
            },
            methods: {
                async fetchGenreMovieLists() {
                    let response = await axios.get('https://api.themoviedb.org/3/genre/movie/list?api_key=' + this.api_key);
                    this.genre_lists = response.data.genres;
                },
                async fetchGenreTvLists() {
                    let response = await axios.get('https://api.themoviedb.org/3/genre/tv/list?api_key=' + this.api_key);
                    this.genre_lists = response.data.genres;
                },
                async fetchLanguageLists() {
                    let response = await axios.get('https://api.themoviedb.org/3/configuration/languages?api_key=' + this.api_key);
                    this.language_lists = response.data;
                },
                async fetchTemplateLists(type) {
                    axios.get("{{ route('api.templates') }}")
                    .then((res) => {
                        this.template_lists = res.data.data.filter((tp) => tp.type === type)
                    })
                },
                async fetchYearLists() {
                    var d = new Date()
                    var thisYear = d.getFullYear()+1
                    var startYear = 1900

                    this.year_lists = new Array(thisYear-startYear).fill(startYear).map((n,i)=>n+i).reverse()
                },
                changeType: function(event) {
                    if (this.formData.type === 'tv') {
                        this.formData.genre = '';
                        this.formData.template = '';
                        this.fetchGenreTvLists()
                        this.fetchTemplateLists('tv')
                    }else{
                        this.formData.genre = '';
                        this.formData.template = '';
                        this.fetchGenreMovieLists()
                        this.fetchTemplateLists('movie')
                    }
                },
                getPrepare: function() {
                    var query = {
                        api_key: this.api_key,
                        page: 1,
                        year: this.formData.year,
                        language: this.formData.language,
                        with_genres: this.formData.genre,
                        sort_by: this.formData.sort_by
                    }

                    var query = jQuery.param(query)
                    var type = this.formData.type

                    this.is_prepare = true

                    axios.get(`https://api.themoviedb.org/3/discover/${type}?${query}`)
                        .then((res) => {
                            this.prepare = res.data
                            this.max_pages = res.data.total_pages
                            this.is_prepare = false
                        })

                },
                exportProgress: function() {
                    var start = this.formData.startPage
                    var finish = this.formData.finishPage
                    this.exports.pages = _.range(start, finish + 1)

                    if (this.formData.type === 'movie') {
                        this.getMoviesTv('movie')
                    }else{
                        this.getMoviesTv('tv')
                    }
                },
                getMoviesTv: function(type) {
                    console.log(type);
                    this.progress = true
                    var pages = this.exports.pages
                    var index_page = this.exports.index_page
                    var total_page = this.exports.total_page
                    var export_to = this.formData.exportTo

                    if ( typeof(pages[index_page]) != 'undefined' && pages[index_page] != null) {
                        var query = {
                            api_key: this.api_key,
                            page: pages[index_page],
                            primary_release_year: this.formData.year,
                            language: this.formData.language,
                            with_genres: this.formData.genre,
                            sort_by: this.formData.sort_by
                        }

                        if (type == 'tv') {
                            var query = {
                                api_key: this.api_key,
                                page: pages[index_page],
                                first_air_date_year: this.formData.year,
                                language: this.formData.language,
                                with_genres: this.formData.genre,
                                sort_by: this.formData.sort_by
                            }
                        }

                        var query = jQuery.param(query)

                        axios.get(`https://api.themoviedb.org/3/discover/${type}?${query}`)
                            .then((res) => {
                                if (res.status == 200) {
                                    this.exports.success += 1
                                    this.exports.total_page = res.data.total_pages
                                }else{
                                    this.exports.failed += 1
                                }

                                this.exports.index_page += 1
                                this.saveCache(res.data, type, export_to)

                                setTimeout(() => {
                                    this.getMoviesTv(type)
                                }, 2000);
                            })
                            .catch((error) => {
                                console.log(error)
                            })
                    }else{
                        this.progress = false
                        this.resetProgress()
                        this.buildExportFile()
                    }
                },
                saveCache: function(data, type, export_to) {
                    let post = {
                        export: export_to,
                        type: type,
                        page: data.page,
                        results: data.results,
                        total_pages: data.total_pages,
                        total_results: data.total_results
                    }

                    axios.post("{{ route('api.exports') }}", post)
                        .then((res) => {})
                },
                resetProgress: function() {
                    this.exports.pages = []
                    this.exports.index_page = 0
                    this.exports.success = 0
                },
                buildExportFile: function() {
                    var post = this.formData

                    axios.post("{{ route('api.build-export-file') }}", post)
                        .then((res) => {
                            this.filename = res.data
                            var data = {
                                filename: res.data
                            }
                            axios.post("{{ route('api.download-file') }}", data)
                                .then((response) => {
                                    this.downloadFile(response.data, data.filename)
                                    this.clearExport()
                                })
                        })
                },
                downloadFile(data, filename, mime, bom) {
                    var blobData = (typeof bom !== 'undefined') ? [bom, data] : [data]
                    var blob = new Blob(blobData, {type: mime || 'application/octet-stream'});
                    if (typeof window.navigator.msSaveBlob !== 'undefined') {
                        window.navigator.msSaveBlob(blob, filename);
                    }
                    else {
                        var blobURL = window.URL.createObjectURL(blob);
                        var tempLink = document.createElement('a');
                        tempLink.style.display = 'none';
                        tempLink.href = blobURL;
                        tempLink.setAttribute('download', filename);

                        if (typeof tempLink.download === 'undefined') {
                            tempLink.setAttribute('target', '_blank');
                        }

                        document.body.appendChild(tempLink);
                        tempLink.click();
                        document.body.removeChild(tempLink);
                        window.URL.revokeObjectURL(blobURL);
                    }
                },
                clearExport: function() {
                    var data = {
                        start_page: this.formData.startPage,
                        finish_page: this.formData.finishPage,
                        filename: this.filename,
                        type: this.formData.type
                    }
                    axios.post('/api/clear-export', data)
                        .then((res) => {
                            console.log(res.data);
                        })
                },
            }
        })
    </script>

    <style>
        .fade-enter-active, .fade-leave-active {
            transition: opacity .5s;
        }
        .fade-enter, .fade-leave-to {
            opacity: 0;
        }
    </style>
@endsection
