<!--
  - Rates.vue
  - Copyright (c) 2024 james@firefly-iii.org.
  -
  - This file is part of Firefly III (https://github.com/firefly-iii).
  -
  - This program is free software: you can redistribute it and/or modify
  - it under the terms of the GNU Affero General Public License as
  - published by the Free Software Foundation, either version 3 of the
  - License, or (at your option) any later version.
  -
  - This program is distributed in the hope that it will be useful,
  - but WITHOUT ANY WARRANTY; without even the implied warranty of
  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  - GNU Affero General Public License for more details.
  -
  - You should have received a copy of the GNU Affero General Public License
  - along with this program.  If not, see https://www.gnu.org/licenses/.
  -->


<template>
    <div>
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
                <div class="box box-primary">
                    <div class="box-header with-border">
                        <h3 class="box-title">{{ $t('firefly.header_exchange_rates_rates') }}</h3>
                    </div>
                    <div class="box-body">
                        <p>
                            {{ $t('firefly.exchange_rates_intro_rates') }}
                        </p>
                    </div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
                <div class="box box-primary">
                    <div class="box-header with-border">
                        <h3 class="box-title">{{ $t('firefly.header_exchange_rates_table') }}</h3>
                    </div>
                    <div class="box-body no-padding">
                        <nav v-if="totalPages > 1">
                            <ul class="pagination">
                                <li v-if="1 === this.page" class="page-item disabled" aria-disabled="true"
                                    :aria-label="$t('pagination.previous')">
                                    <span class="page-link" aria-hidden="true">&lsaquo;</span>
                                </li>
                                <li class="page-item" v-if="1 !== this.page">
                                    <a class="page-link"
                                       :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)"
                                       rel="prev" :aria-label="$t('pagination.next')">&lsaquo;</a>
                                </li>
                                <li v-for="item in this.totalPages"
                                    :class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
                                    <span v-if="item === page" class="page-link" v-text="item"></span>
                                    <a v-if="item !== page" class="page-link"
                                       :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item"
                                       v-text="item"></a>
                                </li>
                                <li v-if="totalPages !== page" class="page-item">
                                    <a class="page-link"
                                       :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)"
                                       rel="next" :aria-label="$t('pagination.next')">&rsaquo;</a>
                                </li>
                                <li v-if="totalPages === page" class="page-item disabled" aria-disabled="true"
                                    :aria-label="$t('pagination.next')">
                                    <span class="page-link" aria-hidden="true">&rsaquo;</span>
                                </li>
                            </ul>
                        </nav>

                        <table class="table table-responsive table-hover">
                            <thead>
                            <tr>
                                <th>{{ $t('form.date') }}</th>
                                <th v-html="$t('form.from_currency_to_currency', {from: from.code, to: to.code})"></th>
                                <th v-html="$t('form.to_currency_from_currency', {from: from.code, to: to.code})"></th>
                                <th>&nbsp;</th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr v-if="loading">
                                <td colspan="4" class="text-center">
                                    <i class="fa fa-refresh fa-spin"></i>
                                </td>
                            </tr>
                            <tr v-if="0 === this.rates.length">
                                <td colspan="4" class="text-center">
                                    <i class="fa fa-battery-empty"></i>
                                </td>
                            </tr>
                            <tr v-for="(rate, index) in rates" :key="rate.key">
                                <td>
                                    <input
                                        ref="date"
                                        :value="rate.date_field"
                                        autocomplete="off"
                                        class="form-control"
                                        name="date[]"
                                        type="date"
                                        v-bind:placeholder="$t('firefly.date')"
                                        v-bind:title="$t('firefly.date')"
                                    >
                                </td>
                                <td>
                                    <!-- (<span v-text="rate.rate_id"></span>) -->
                                    <input type="number" class="form-control" min="0" step="any" v-model="rate.rate">
                                </td>
                                <td>
                                    <!-- (<span v-text="rate.inverse_id"></span>) -->
                                    <input type="number" class="form-control" min="0" step="any" v-model="rate.inverse">
                                </td>
                                <td>
                                    <div class="btn-group">
                                        <button
                                            :disabled="saveButtonDisabled(index)"
                                            class="btn btn-default" :title="$t('firefly.submit')"
                                            @click="updateRate(index)">
                                            <em class="fa fa-save"></em>
                                        </button>
                                        <button class="btn btn-danger" :title="$t('firefly.delete')"
                                                @click="deleteRate(index)">
                                            <em class="fa fa-trash"></em>
                                        </button>
                                    </div>
                                </td>
                            </tr>
                            </tbody>
                        </table>

                        <nav v-if="totalPages > 1">
                            <ul class="pagination">
                                <li v-if="1 === this.page" class="page-item disabled" aria-disabled="true"
                                    :aria-label="$t('pagination.previous')">
                                    <span class="page-link" aria-hidden="true">&lsaquo;</span>
                                </li>
                                <li class="page-item" v-if="1 !== this.page">
                                    <a class="page-link"
                                       :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)"
                                       rel="prev" :aria-label="$t('pagination.next')">&lsaquo;</a>
                                </li>
                                <li v-for="item in this.totalPages"
                                    :class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
                                    <span v-if="item === page" class="page-link" v-text="item"></span>
                                    <a v-if="item !== page" class="page-link"
                                       :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item"
                                       v-text="item"></a>
                                </li>
                                <li v-if="totalPages !== page" class="page-item">
                                    <a class="page-link"
                                       :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)"
                                       rel="next" :aria-label="$t('pagination.next')">&rsaquo;</a>
                                </li>
                                <li v-if="totalPages === page" class="page-item disabled" aria-disabled="true"
                                    :aria-label="$t('pagination.next')">
                                    <span class="page-link" aria-hidden="true">&rsaquo;</span>
                                </li>
                            </ul>
                        </nav>

                    </div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
                <form class="form-horizontal nodisablebutton" @submit="submitRate">
                    <div class="box box-default">
                        <div class="box-header with-border">
                            <h3 class="box-title">{{ $t('firefly.add_new_rate') }}</h3>
                        </div>
                        <div class="box-body">
                            <p v-if="newError !=''" v-text="newError" class="text-danger">

                            </p>
                            <div class="form-group" id="name_holder">
                                <label for="ffInput_date" class="col-sm-4 control-label"
                                       v-text="$t('form.date')"></label>
                                <div class="col-sm-8">
                                    <input class="form-control" type="date" name="date" id="ffInput_date"
                                           :disabled="posting"
                                           autocomplete="off" spellcheck="false" v-model="newDate">
                                </div>
                            </div>
                            <div class="form-group" id="rate_holder">
                                <label for="ffInput_rate" class="col-sm-4 control-label"
                                       v-text="$t('form.rate')"></label>
                                <div class="col-sm-8">
                                    <input class="form-control" type="number" name="rate" id="ffInput_rate"
                                           :disabled="posting"
                                           autocomplete="off" spellcheck="false" v-model="newRate" step="any">
                                    <p class="help-block"
                                       v-text="$t('firefly.help_rate_form', {from: from_code, to: to_code})">

                                    </p>
                                </div>
                            </div>
                        </div>
                        <div class="box-footer">
                            <button type="submit" class="nodisablebutton btn pull-right btn-success"
                                    v-text="$t('firefly.save_new_rate')"></button>
                        </div>
                    </div>

                </form>
            </div>
        </div>
    </div>
</template>
<script>

import format from "date-fns/format";

export default {
    name: "Rates",
    data() {
        return {
            newDate: '',
            newRate: '1.0',
            newError: '',
            rates: [],
            tempRates: {},
            from_code: '',
            to_code: '',
            from: {
                name: ''
            },
            to: {
                name: ''
            },
            loading: true,
            posting: false,
            updating: false,
            page: 1,
            totalPages: 1,
        };
    },
    mounted() {
        // get from and to code from URL
        this.newDate = format(new Date, 'yyyy-MM-dd');
        let parts = window.location.pathname.split('/');
        this.from_code = parts[parts.length - 2].toUpperCase();
        this.to_code = parts[parts.length - 1].toUpperCase();

        const params = new Proxy(new URLSearchParams(window.location.search), {
            get: (searchParams, prop) => searchParams.get(prop),
        });
        this.page = parseInt(params.page ?? 1);


        this.downloadCurrencies();
        this.rates = [];
        this.downloadRates(this.page);
    },
    methods: {
        submitRate: function (e) {
            if (e) e.preventDefault();
            this.posting = true;

            axios.post("./api/v1/exchange-rates", {
                from: this.from_code,
                to: this.to_code,
                rate: this.newRate,
                date: this.newDate,
            }).then(() => {
                this.posting = false;
                this.downloadRates(1);
            }).catch((err) => {
                this.posting = false;
                this.newError = err.response.data.message;
            });


            return false;
        },
        saveButtonDisabled: function (index) {
            return ('' === this.rates[index].rate && '' === this.rates[index].inverse) || this.updating;
        },
        updateRate: function (index) {
            let parts = this.spliceKey(this.rates[index].key);
            if (0 === parts.length) {
                return;
            }
            console.log('These are the parts', parts);
            if ('' !== this.rates[index].rate) {
                //console.log('[a] Rate info is', this.rates[index]);
                this.updating = true;
                if (0 === parseInt(this.rates[index].rate_id)) {
                    console.log('[a] POST, not PUT.');
                    axios.post('./api/v1/exchange-rates',
                        {
                            from: this.from_code,
                            to: this.to_code,
                            rate: this.rates[index].rate,
                            date: this.rates[index].date_field
                        })
                        .then(() => {
                            this.updating = false;
                        });
                }
                if (0 !== parseInt(this.rates[index].rate_id)) {
                    console.log('[a] PUT, not POST.');
                    axios.put('./api/v1/exchange-rates/' + this.rates[index].rate_id, {rate: this.rates[index].rate})
                        .then(() => {
                            this.updating = false;
                        });
                }
            }
            if ('' !== this.rates[index].inverse) {
                //console.log('[b] Rate info is', this.rates[index]);
                this.updating = true;
                if (0 === parseInt(this.rates[index].inverse_id)) {
                    console.log('[b] POST, not PUT.');
                    // post, not put
                    axios.post('./api/v1/exchange-rates',
                        {
                            // remember, this is in reverse.
                            from: this.to_code,
                            to: this.from_code,
                            rate: this.rates[index].inverse,
                            date: this.rates[index].date_field
                        })
                        .then(() => {
                            this.updating = false;
                        });
                }
                if (0 !== parseInt(this.rates[index].inverse_id)) {
                    console.log('[b] PUT, not POST.');
                    axios.put('./api/v1/exchange-rates/' + this.rates[index].inverse_id, {rate: this.rates[index].inverse})
                        .then(() => {
                            this.updating = false;
                        });
                }
            }
        },
        deleteRate: function (index) {
            // console.log(this.rates[index].key);
            let parts = this.spliceKey(this.rates[index].key);

            if (0 === parts.length) {
                return;
            }
            let rateId = parseInt(this.rates[index].rate_id);
            let inverseId = parseInt(this.rates[index].inverse_id);
            // delete A to B
            if (rateId > 0) {
                axios.delete('./api/v1/exchange-rates/' + rateId);
            }
            if (inverseId > 0) {
                axios.delete('./api/v1/exchange-rates/' + inverseId);
            }

            this.rates.splice(index, 1);
        },

        spliceKey: function (key) {
            if (key.length !== 18) {
                return [];
            }
            let main = key.split('_');
            if (3 !== main.length) {
                return [];
            }
            let date = new Date(main[2]);
            return {
                from: main[0],
                to: main[1],
                date: date,
            };
        },
        downloadCurrencies: function () {
            console.log('Now downloading currencies.');
            this.loading = true;
            axios.get("./api/v1/currencies/" + this.from_code).then((response) => {
                this.from = {
                    id: response.data.data.id,
                    code: response.data.data.attributes.code,
                    name: response.data.data.attributes.name,
                }
            });
            axios.get("./api/v1/currencies/" + this.to_code).then((response) => {
                // console.log(response.data.data);
                this.to = {
                    id: response.data.data.id,
                    code: response.data.data.attributes.code,
                    name: response.data.data.attributes.name,
                }
            });
        },
        downloadRates: function (page) {
            this.tempRates = {};
            this.loading = true;
            console.log('Now downloading rates.', page);
            axios.get('./api/v1/exchange-rates/' + this.from_code + '/' + this.to_code + '?page=' + page).then((response) => {
                for (let i in response.data.data) {
                    if (response.data.data.hasOwnProperty(i)) {
                        console.log('Downloaded entry #' + i);
                        let current = response.data.data[i];
                        let date = new Date(current.attributes.date);
                        let from_code = current.attributes.from_currency_code.toUpperCase();
                        let to_code = current.attributes.to_currency_code.toUpperCase();
                        let rate = current.attributes.rate;
                        let inverse = '';
                        let rate_id = current.id;
                        let inverse_id = '0';
                        let key = from_code + '_' + to_code + '_' + format(date, 'yyyy-MM-dd');
                        console.log('Key is now "' + key + '"');

                        // perhaps the returned rate is actually the inverse rate.
                        if (from_code === this.to_code && to_code === this.from_code) {
                            // console.log('Inverse rate found!');
                            key = to_code + '_' + from_code + '_' + format(date, 'yyyy-MM-dd');
                            rate = '';
                            // new: set rate id to zero.
                            rate_id = '0';
                            inverse = current.attributes.rate;
                            inverse_id = current.id;
                            console.log('Key updated to "' + key + '"');
                        }

                        if (!this.tempRates.hasOwnProperty(key)) {
                            console.log('New entry stored');
                            this.tempRates[key] = {
                                key: key,
                                date: date,
                                rate_id: rate_id,
                                inverse_id: inverse_id,
                                date_formatted: format(date, this.$t('config.date_time_fns')),
                                date_field: current.attributes.date.substring(0, 10),
                                rate: rate,
                                inverse: '',
                            };
                        }

                        // inverse is not "" and existing inverse is ""?
                        if (this.tempRates.hasOwnProperty(key) && inverse !== '' && this.tempRates[key].inverse === '') {
                            this.tempRates[key].inverse = inverse;
                            this.tempRates[key].inverse_id = inverse_id;
                        }
                        // rate is not "" and existing rate is ""?
                        if (this.tempRates.hasOwnProperty(key) && rate !== '' && this.tempRates[key].rate === '') {
                            this.tempRates[key].rate = rate;
                            this.tempRates[key].rate_id = rate_id;
                        }
                        console.log('Found exchange rate #' + this.tempRates[key].rate_id + ' with inverse #' + this.tempRates[key].inverse_id);


                    }
                }
                this.totalPages = parseInt(response.data.meta.pagination.total_pages);
                this.loading = false;
                this.rates = Object.values(this.tempRates);
                // console.log('Do not download more pages. Now on page ' + this.page + ' of ' + this.totalPages);
            });
        }
    },

}

</script>
