
<daily>
    <style scoped>
    </style>

    <!--　日別表示　-->

    <div id="ipat_history_list" class="ipat_history_list">
        <div class="Sort_Btn fc">
            <div class="Sort_Field">
                <span class="Sort_OpenBtn_Label"></span>
                <select class="Sort_Select" value={ selected_sort_option } onchange={ change_sort_option }>
                    <option each={ option in sort_options } value={ option.value } selected={ selected_sort_option === option.value }>{ option.label }</option>
                </select>
            </div>
        </div>

        <div class="Race_Infomation_Box" if={ bet_list && Object.keys(bet_list).length <= 0 }>投票履歴はございません。</div>

        <div class="Balance_List" if={ bet_list } each={ bet, key in bet_list }>
            <ul class="Balance_ListInner">
                <li class="Balance_ListItem">
                    <div>
                        <span class="{kakutei_label[bet.detail.state].class}">{kakutei_label[bet.detail.state].label}</span>
                        <span class="{henkan_label[bet.detail.refund_flag].class}">{henkan_label[bet.detail.refund_flag].label}</span>
                        <a href="{ args.keirin_url }{ bet.race_id.substr(8,2) == 91 ? 'pist6' : 'race' }/{kakutei_label[bet.detail.state].pid}/?race_id={bet.race_id}">{ jyo_list[bet.race_id.substr(8,2)] } { bet.race_id.substr(10,2).replace(/^0/, '') }R { bet.detail.race_name }</a>
                    </div>
                    <div>
                        <div>
                            <dl>
                                <dt>購入</dt>
                                <dd class="price_detail">{ number_format(bet.detail.bet_total) }<span>円</span></dd>
                            </dl>
                            <dl class="{ edit_money_class(bet.detail.payback) }">
                                <dt>払戻</dt>
                                <dd class="price_detail">{ number_format(bet.detail.payback) }<span>円</span></dd>
                            </dl>
                        </div>
                    </div>
                    <span class="list_toggle">開く</span>
                </li>
            </ul>
            <div class="Balance_ListToggle Result_toggleInner">
                <ul>
                    <li each={ val, key in bet.detail.bet_list } class="{ (val.is_hit == 1) ? 'Payout01' : '' }  Balance_ListToggleItem { val.houshiki == '0' ? 'normal' : '' }">
                        <div class="ListToggleItem_01">
                            <span class="{shikibetu_class[val.shikibetu]} label">{val.name1 || val.shikibetu_name}</span>
                            <span class="Result01" if={ val.is_hit == 1 && val.payback_flag == 0 }>的</span>
                            <!-- モック追加 -->
                            <span class="Result02" if={ val.is_hit == 1 && val.payback_flag == 2 }>特</span>
                            <!-- モック追加 -->
                            <span class="{ (val.is_hit == 1) ? 'PayoutBetName' : '' }" if={val.shikibetu != 1}>{ edit_bet_name(val) }</span><!--{ houshiki[val.shikibetu + val.houshiki] }-->
                            <!-- モック追加 -->
                            <span class="Return" if={ val.status == 1 && val.payback_flag == 1 }>返還</span>
                            <!-- モック追加 -->
                            <span class="typeTag keirin" if={ val.is_netkeirin}>netkeirin</span>
                            <span class="typeTag tipstar" if={ !val.is_netkeirin}>TIPSTAR</span>
                            <span class="date">{ edit_save_date(val.create_datetime || val.created_at) }</span>
                            <span class="list_toggle">開く</span>
                        </div>
                        <virtual if={ val.houshiki != 0 } >
                            <div class="ListToggleItem_03 Result_toggleInner">
                                <div class="BetTable">
                                    <div id="select_kumiawase" class="kaime_view FormationType">
                                        <div class="LabelWrap" if={ val.kaime1 }>
                                            <div class="LabelArrow" if={ val.houshiki != 2 }> <span>{ edit_arrow_label(val.shikibetu, val.houshiki, '1') } </span> </div>
                                            <div class="Num">
                                                <div class="Shaban_InBox" each={ syaban, idx in val.kaime1.split('-') }><span class="Wakuban Waku{ (val.shikibetu == 3 || val.shikibetu == 4) ? '1' : syaban }">{syaban}</span></div>
                                            </div>
                                        </div>
                                        <div class="LabelWrap" if={ val.kaime2 }>
                                            <div class="LabelArrow" if={ val.houshiki != 2 }> <span>{ edit_arrow_label(val.shikibetu, val.houshiki, '2') } </span> </div>
                                            <div class="Num">
                                                <div class="Shaban_InBox" each={ syaban, idx in val.kaime2.split('-') }><span class="Wakuban Waku{ (val.shikibetu == 3 || val.shikibetu == 4) ? '1' : syaban }">{syaban}</span></div>
                                            </div>
                                        </div>
                                        <div class="LabelWrap" if={ val.kaime3 }>
                                            <div class="LabelArrow" if={ val.houshiki != 2 }> <span>{ edit_arrow_label(val.shikibetu, val.houshiki, '3') }</span> </div>
                                            <div class="Num">
                                                <div class="Shaban_InBox" each={ syaban, idx in val.kaime3.split('-') }><span class="Wakuban Waku{ (val.shikibetu == 3 || val.shikibetu == 4) ? '1' : syaban }">{syaban}</span></div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="ListToggleItem_03_total">
                                    <dl class="BalanceData">
                                        <dt>{ val.combinations.length}点<span>計</span>{ number_format(val.total_bet_money || val.total_vote_money) }円</dt>
                                        <dd>{ number_format(val.payback) }円</dd>
                                    </dl>
                                </div><!-- /.ListToggleItem_03_total -->
                            </div>
                            <div class="Develop_ToggleWrap Result_toggleInner">
                                <a href="javascript:void(0)" class="develop_toggle">展開する<span></span></a>
                                <div class="develop_wrap Result_toggleInner">
                                    <div class="ListToggleItem_02_develop { (val.hit_combinations && val.hit_combinations[kaime]) ? 'BalanceData' : '' }" each={ kaime, idx in val.combinations }>
                                        <ul class="Arrow01">
                                            <li each={ syaban, key in kaime.split('-') }><span class="UmaBan Waku{ (val.shikibetu == 3 || val.shikibetu == 4) ? '1' : syaban.replace(/^0/, '') } { edit_kaime_class(val.shikibetu) }">{ syaban.replace(/^0/, '') }</span><!--svg class="Icon_Shirushi01 Icon_Honmei"><use xlink:href="/common/img/icon/icon_shirushi.svg#icon-honmei"></use></svg--></li>
                                            <!--li><span class="UmaBan Waku4">4</span><svg class="Icon_Shirushi01 Icon_Taikou"><use xlink:href="/common/img/icon/icon_shirushi.svg#icon-taikou"></use></svg></li>
                                            <li><span class="UmaBan Waku1">1</span><svg class="Icon_Shirushi01 Icon_Kurosan"><use xlink:href="/common/img/icon/icon_shirushi.svg#icon-kurosan"></use></svg></li-->
                                        </ul>
                                        <dl>
                                            <dt if={ !val.refund_combinations }>{ val.bet_money || val.vote_money }円</dt>
                                            <dt if={ val.refund_combinations }>{ val.bet_money || val.vote_money }円</dt>

                                            <dd if={ (!val.hit_combinations || !val.hit_combinations[kaime]) && !val.refund_combinations[kaime] }>0円</dd>
                                            <dd if={ val.hit_combinations && val.hit_combinations[kaime] && !val.refund_combinations[kaime] }>{ number_format(val.hit_combinations[kaime] * (val.bet_money / 100 || val.vote_money / 100) ) }円</dd>
                                            <dd if={ val.refund_combinations && val.refund_combinations[kaime] }>
                                                <span class="{henkan_label[1].class}">{henkan_label[1].label}</span>
                                            </dd>
                                        </dl>
                                    </div>
                                </div>
                            </div>
                        </virtual>
                        <virtual if={ val.houshiki == 0 }>
                            <div class="ListToggleItem_02">
                                <ul class="Arrow01">
                                    <li if={ val.kaime1 }><span class="UmaBan Waku{ (val.shikibetu == 3 || val.shikibetu == 4) ? '1' : val.kaime1 } { edit_kaime_class(val.shikibetu) }">{ val.kaime1 }</span></li>
                                    <li if={ val.kaime2 }><span class="UmaBan Waku{ (val.shikibetu == 3 || val.shikibetu == 4) ? '1' : val.kaime2 } { edit_kaime_class(val.shikibetu) }">{ val.kaime2 }</span></li>
                                    <li if={ val.kaime3 }><span class="UmaBan Waku{ (val.shikibetu == 3 || val.shikibetu == 4) ? '1' : val.kaime3 } { edit_kaime_class(val.shikibetu) }">{ val.kaime3 }</span></li>
                                </ul>
                                <dl>
                                    <dt if={ !val.refund_combination }>{ number_format(val.bet_money || val.vote_money) }円</dt>
                                    <dt if={ val.refund_combination }>{ number_format(bet_calc(val)) }円</dt>
                                    <dd if={ val.refund == 0 }>{ number_format(val.payback) }円</dd>
                                    <dd if={ val.refund != 0 }>
                                        <span class="{henkan_label[1].class}">{henkan_label[1].label}</span>
                                    </dd>
                                </dl>
                            </div>
                        </virtual>
                    </li>
                </ul>
            </div><!-- /.Balance_ListToggle -->
        </div><!-- /.Balance_List -->
        <ul class="typetag_info" if={ bet_list && Object.keys(bet_list).length> 0 }>
            <li><span class="netkeirin"></span>:netkeirinで投票</li>
            <li><span class="tipstar"></span>:TIPSTARで投票</li>
        </ul>
    </div><!-- /#ipat_history_list -->
    <!--　日別表示　-->
    <script>

    number_format(num){
        return num.toString().replace(/(\d+?)(?=(?:\d{3})+$)/g, function(x) {
            return x + ',';
        });
    }

    edit_save_date(create_datetime){
        var tmp_date = create_datetime.split(' ');
        return tmp_date[1].substr(0, 5);
    }

    sort_event(sort_key, mode){
        if(!mode){
            mode = 'asc';
        }
        self.bet_list = self.act_sort(self.bet_base_list, sort_key, mode);
    }

    select_sort_option(option_key){
        self.selected_sort_option = option_key;
        self.apply_sort_by_option(self.selected_sort_option);
        self.update();
    }

    change_sort_option(e){
        self.select_sort_option(e.target.value);
    }

    edit_money_class(money){
        if(money <= 0){
            //console.log('m');
            return '';
        }else{
            return 'BalanceData';
        }
    }

    edit_kaime_class(shikibetu)
    {
        if(4 == shikibetu || 6 == shikibetu || 9 == shikibetu){ // 枠単,2車単,３連単
            // 馬番の間(矢印)
            return 'Kaime_Arrow'
        }else{
            // 馬番の間(ハイフン)
            return 'Hyphen';
        }
    }

    edit_arrow_label(shikibetu, houshiki, chaku)
    {
        if (typeof shikibetu === 'number' && Number.isInteger(shikibetu)) {
          shikibetu = String(shikibetu);
        }
        if (typeof houshiki === 'number' && Number.isInteger(houshiki)) {
          houshiki = String(houshiki);
        }
        var idx = shikibetu + houshiki;
        var ary_idx = parseInt(chaku) - 1;
        if(self.houshiki_attr[idx][ary_idx]){
            return self.houshiki_attr[idx][ary_idx];
        }else if(idx == 11){
            //単勝
            return self.houshiki_attr[idx]['label'][ary_idx];
        }
    }

    edit_bet_name(val){
        var tmp_bet = self.ipat.cvt_bet(val.cart_item_id, 100, []);
        if(tmp_bet.houshiki == 1 && (tmp_bet.shikibetu == 3 || tmp_bet.shikibetu == 4)){
            var comb = val.combinations ? val.combinations.length : 0;
            return sprintf("%s%s組", tmp_bet.houshiki_name, comb);
        }else{
            return tmp_bet.houshiki_name + tmp_bet.kumi_name;
        }
    }

    object_length(obj){
        return Object.entries(obj).length;
    }

    refund_calc(refund_combination, kaime){
        var refund = 0;

        if(refund_combination[kaime]){
            refund = refund_combination[kaime];
        }

        return refund;
    }

    bet_calc(val){
        var bet_money = val.bet_money;
        var kaime = '0' + val.kaime1;

        if(val.kaime2){
            kaime = kaime + '-0' + val.kaime2;
        }

        if(val.kaime3){
            kaime = kaime + '-0' + val.kaime3;
        }

        var refund = val.refund_combination[kaime];

        if(!refund){
            kaime = kaime.replace(/-/g, '');
        }

        refund = val.refund_combination[kaime];

        if(refund){
            bet_money = bet_money - refund;
        }

        return bet_money;
    }

    // アプリのフッターメニュー切り替え時のデータ更新用
    appli_update_daily_balance = function(){
        console.log('appli_update_daily_balance');
        self.bet_list = {};
        self.bet_base_list = {};
        self.ipat = new IpatDataModel();
        self.shikibetu = self.ipat.get_shikibetu();
        self.houshiki = self.ipat.get_houshiki();
        self.jyo_cd = null;
        self.show_data({});
    }

    "use strict";

    get_current_date(){
        const now = new Date();
        const year = now.getFullYear();
        let month = (now.getMonth() + 1).toString();
        if (month.length === 1) month = '0' + month;
        let day = now.getDate().toString();
        if (day.length === 1) day = '0' + day;
        return year + month + day;
    }

    var self = this;
    self.args = self.opts;
    self.debug = true;
    self.param = null;
    self.bet_list = {};
    self.bet_base_list = {};
    self.jyo_list = JSON.parse(self.args.jyo_list);
    self.shikibetu = {};
    self.houshiki = {};
    self.shikibetu_class = {
        1: 'Tansho',
        2: 'Fukusho',
        3: 'Wakuren',
        4: 'Wakutan',
        5: 'Umaren',
        7: 'Wide',
        6: 'Umatan',
        8: 'Fuku3',
        9: 'Tan3',
    }
    self.kakutei_label = {
        0: {
            pid: 'entry',
            label: '未',
            class: 'miKakutei'
        },
        1: {
            pid: 'result',
            label: '確',
            class: 'Kakutei'
        }
    }
    self.henkan_label = {
        0: {
            pid: '',
            label: '',
            class: ''
        },
        1: {
            pid: 'henkan',
            label: '返還',
            class: 'Icon_GradeType Icon_GradeType2'
        },
        2: {
            pid: '',
            label: '',
            class: ''
        }
    }
    self.jyo_cd = null;
    self.sort_type = {
        'sort_race' : '',
        'sort_hasso_time' : '',
        'sort_create_time' : '',
        'payback' : '',
    };
    self.selected_sort_option = 'sort_create_time_asc';
    self.sort_options = [
        { value: 'sort_race_asc', label: 'レースが早い順' },
        { value: 'sort_race_desc', label: 'レースが遅い順' },
        { value: 'sort_hasso_time_asc', label: '発走時間が早い順' },
        { value: 'sort_hasso_time_desc', label: '発走時間が遅い順' },
        { value: 'sort_create_time_asc', label: '保存時間が早い順' },
        { value: 'sort_create_time_desc', label: '保存時間が遅い順' },
        { value: 'payback_desc', label: '払戻金額が高い順' },
        { value: 'payback_asc', label: '払戻金額が低い順' },
    ];
    self.sort_option_map = {
        'sort_race_asc': { sort_key: 'sort_race', mode: 'asc' },
        'sort_race_desc': { sort_key: 'sort_race', mode: 'desc' },
        'sort_hasso_time_asc': { sort_key: 'sort_hasso_time', mode: 'asc' },
        'sort_hasso_time_desc': { sort_key: 'sort_hasso_time', mode: 'desc' },
        'sort_create_time_asc': { sort_key: 'sort_create_time', mode: 'asc' },
        'sort_create_time_desc': { sort_key: 'sort_create_time', mode: 'desc' },
        'payback_asc': { sort_key: 'payback', mode: 'asc' },
        'payback_desc': { sort_key: 'payback', mode: 'desc' },
    };
    self.apply_sort_by_option = function(option_key){
        var selected = self.sort_option_map[option_key] || self.sort_option_map['sort_create_time_asc'];
        self.bet_list = self.act_sort(self.bet_base_list, selected.sort_key, selected.mode);
    };
    self.houshiki_attr = {
        // 単勝
        '11': {in: [1,0,0], all: [0,0,0], check: [0,0,0], label: ['1着','--','--']}, // 通常
        // 枠複
        '30': ['枠1','枠2','--'], // 通常
        '31': ['枠1','枠2','--'],  // フォーメーション
        '33': ['軸','相手','--'],  // ながし
        // 車連
        '50': ['--','--','--'], // 通常
        '51': ['車1','車2','--'],  // フォーメーション
        '52': ['選択','--','--'], // BOX
        '53': ['軸','相手','--'],  // ながし
        // ワイド
        '70': ['--','--','--'], // 通常
        '71': ['車1','車2','--'],  // フォーメーション
        '72': ['選択','--','--'], // BOX
        '73': ['軸','相手','--'],  // ながし
        // 2車単
        '60': ['1着','2着','--'], // 通常
        '61': ['軸','相手','--'],  // フォーメーション
        '62': ['選択','--','--'], // BOX
        '63': ['1着軸','相手','--'],  // 1着ながし
        '64': ['2着軸','相手','--'],  // 2着ながし
        // 3連複
        '80': ['車1','車2','車3'], // 通常
        '81': ['車1','車2','車3'],   // フォーメーション
        '82': ['選択','--','--'],  // BOX
        '83': ['軸','相手','--'],  // 軸1頭ながし
        '86': ['軸1','軸2','相手'],   // 軸2頭ながし
        // 3連単
        '90': ['1着 ','2着 ','3着'], // 通常
        '91': ['1着 ','2着 ','3着'],   // フォーメーション
        '92': ['選択','--','--'], // BOX
        '93': ['1着軸','相手','--'],  // 1着ながし
        '94': ['2着軸','相手','--'],  // 2着ながし
        '95': ['3着軸','相手','--'],  // 3着ながし
        '96': ['1着軸','2着軸','相手'],   // 1,2着ながし
        '97': ['1着軸','3着軸','相手'],   // 1,3着ながし
        '98': ['2着軸','3着軸','相手'],   // 2,3着ながし
        // 2枠単
        '40': ['1着','2着','--'], // 通常
        '41': ['1着','2着','--'],  // フォーメーション
        '42': ['選択','--','--'], // BOX
        '43': ['1着軸','相手','--'],  // 1着ながし
        '44': ['2着軸','相手','--'],  // 2着ながし
    };
    self.current_date = self.get_current_date();
    if (self.debug) console.log('sel.args: %O', self.args);

    self.on('update', function() {
        //	     console.error('self.update()');
    });
    self.on('updated', function() {
        //	     console.error('self.updated()');
    });

    /*
     * 画面初期化(mount)
     */
    self.on('mount', function() {
        if (self.debug)  console.log('mount %s', self.args.tag_name);
        self.args.obs.trigger('tag_mounted', {tag: self.args.tag_name});
    });

    /*
     * 画面表示(parent -> trigger -> render_xxxx)
     */
    self.args.obs.on('render_' + self.args.tag_name, function(p) {
        if (self.debug) console.log('render_%s start p: %O', self.args.tag_name, p);
        self.bet_base_list = {};
        self.ipat = new IpatDataModel();
        self.shikibetu = self.ipat.get_shikibetu();
        self.houshiki = self.ipat.get_houshiki();
        self.jyo_cd = null;
        self.show_data(p);
    });

    /*
     * データ取得、編集
     */
    self.show_data = async function(p) {
        self.bet_base_list = {};
        self.bet_list = {};
        self.ipat = new IpatDataModel();
        self.shikibetu = self.ipat.get_shikibetu();
        self.houshiki = self.ipat.get_houshiki();
        self.jyo_cd = null;

        // 二重実行防止: 実行中なら何もせず return（保留せず1回だけ実行）
        if (self._show_data_running) {
            return;
        }
        self._show_data_running = true;

        if (self.debug) console.log('self.show_data');
        if(p['jyo']){
            self.jyo_cd = p['jyo'];
        }
        self.type = '0'; // 0:すべての投票先 1:netkeirin 2:TIPSTAR
        if(p['type'] == '1'){
            self.type = '1';
        }else if(p['type'] == '2'){
            self.type = '2';
        }
        if(p['date']){
            self.current_date = p['date'];
        }
        var now = new Date();
        self.year = self.current_date ? self.current_date.substr(0,4) : now.getFullYear();
        if(self.current_date && self.current_date.substr(4,2)){
            self.month = self.current_date.substr(4,2);
            self.day = self.current_date.substr(6,2);
        }else{
            var month = "0" + String(now.getMonth()+1);
            self.month = month.substr(-2);
            self.day = "0" + String(now.getDate());
        }

        try {
            // netkeirin投票データ取得
            var netkeirinData = self.type != '2' ? await self.get_netkeirin_myshushi_sum_data() : {};
            console.log('netkeirinData: %O', netkeirinData);
            // TIPSTAR連携データ取得
            var myshushiData = self.type != '1' ? await self.get_myshushi_data() : {};
            console.log('myshushiData: %O', myshushiData);

            var myshushi_ary_sum = Object.keys(myshushiData).length > 0 ? myshushiData.ary_sum : {};
            var netkeirin_data_list = Object.keys(netkeirinData).length > 0 ? netkeirinData : {};
            console.log('myshushi_ary_sum: %O', myshushi_ary_sum);
            console.log('netkeirin_data_list: %O', netkeirin_data_list);
            self.total_money = self.merge_shushi_data(myshushi_ary_sum, netkeirin_data_list, 'daily');
            if(Object.keys(self.total_money).length > 0){
                self.is_data = true;
                self.date_list = Object.keys(self.total_money);
                if(!p['date']){
                    self.current_date = String(Math.max(...self.date_list));
                    var now = new Date();
                    self.year = self.current_date ? self.current_date.substr(0,4) : now.getFullYear();
                    if(self.current_date && self.current_date.substr(4,2)){
                        self.month = self.current_date.substr(4,2);
                    }else{
                        var month = "0" + String(now.getMonth()+1);
                        self.month = month.substr(-2);
                    }
                }

                // netkeirin投票データ取得(日別)
                var netkeirinShushiData = self.type != '2' ? await self.get_netkeirin_myshushi_data() : {};
                console.log('netkeirinShushiData: %O', netkeirinShushiData);

                var myshushi_data_list = Object.keys(myshushiData).length > 0 ? Object.keys(myshushiData.bet_list) : [];
                var myshushi_bet_list = Object.keys(myshushiData).length > 0 ? myshushiData.bet_list : {};
                var netkeirin_data_list = netkeirinData['daily'];
                if (myshushi_data_list.includes(self.current_date)) {
                    if (self.jyo_cd && self.jyo_cd != 1) {
                        if (myshushi_bet_list[self.current_date]) {
                            for (var race_id in myshushi_bet_list[self.current_date]) {
                                if (self.jyo_cd == race_id.substr(8, 2)) {
                                    if(!self.bet_base_list[race_id]){
                                        self.bet_base_list[race_id] = {};
                                    }
                                    self.bet_base_list[race_id] = myshushi_bet_list[self.current_date][race_id];
                                    self.bet_base_list[race_id]['sort_hasso_time'] = self.toTimestamp(myshushi_bet_list[self.current_date][race_id]['hasso_time']);
                                }
                            }
                        }
                    } else {
                        self.bet_base_list = myshushi_bet_list[self.current_date];
                        if (myshushi_bet_list[self.current_date]) {
                            for (var race_id in myshushi_bet_list[self.current_date]) {
                                self.bet_base_list[race_id]['sort_hasso_time'] = self.toTimestamp(myshushi_bet_list[self.current_date][race_id]['hasso_time']);
                                console.log(self.bet_base_list[race_id]['sort_hasso_time']);
                            }
                        }
                    }
                }
                if (self.current_date in netkeirinShushiData) {
                    var netkeirin_bet_list = netkeirinShushiData[self.current_date];
                    for(var race_id in netkeirin_bet_list){
                        // netkeirin投票フラグを立てる
                        netkeirin_bet_list[race_id]['vote_list'].forEach(function(vote) {
                            vote.is_netkeirin = true;
                        });
                        if(self.jyo_cd && self.jyo_cd != 1 && self.jyo_cd != race_id.substr(8, 2)) continue;
                        if(race_id in self.bet_base_list){
                            self.bet_base_list[race_id]['bet_total'] += netkeirin_bet_list[race_id]['vote_total'];
                            self.bet_base_list[race_id]['payback'] += netkeirin_bet_list[race_id]['payback'];
                            self.bet_base_list[race_id]['bet_list'] = self.bet_base_list[race_id]['bet_list'].concat(netkeirin_bet_list[race_id]['vote_list']);
                        }else{
                            if(!self.bet_base_list[race_id]){
                                self.bet_base_list[race_id] = {};
                            }
                            self.bet_base_list[race_id]['bet_total'] = (self.bet_base_list[race_id]['bet_total'] || 0) + (netkeirin_bet_list[race_id]['vote_total'] || 0);
                            self.bet_base_list[race_id]['payback'] = (self.bet_base_list[race_id]['payback'] || 0) + (netkeirin_bet_list[race_id]['payback'] || 0);
                            self.bet_base_list[race_id]['bet_list'] = netkeirin_bet_list[race_id]['vote_list'];
                            self.bet_base_list[race_id]['payback_flag'] = netkeirin_bet_list[race_id]['payback_flag'];
                            self.bet_base_list[race_id]['race_name'] = netkeirin_bet_list[race_id]['race_name'];
                            self.bet_base_list[race_id]['refund_flag'] = netkeirin_bet_list[race_id]['refund_flag'];
                            self.bet_base_list[race_id]['sort_create_time'] = self.toTimestamp(netkeirin_bet_list[race_id]['sort_created_at']);
                            self.bet_base_list[race_id]['sort_race'] = race_id.substr(8,4); //: "2209"
                            self.bet_base_list[race_id]['state'] = netkeirin_bet_list[race_id]['status'];
                            self.bet_base_list[race_id]['sort_hasso_time'] = self.toTimestamp(netkeirin_bet_list[race_id]['hasso_time']);

                        }
                    }
                }
                // ソート用にタイムスタンプに変換
                //for(var race_id in self.bet_base_list){
                //    for(var key in self.bet_base_list[race_id]['bet_list']){
                //        self.bet_base_list[race_id]['bet_list'][key]['sort_hasso_time'] = self.toTimestamp(self.bet_base_list[race_id]['bet_list'][key]['hasso_time']);
                //    }
                //}
                self.apply_sort_by_option(self.selected_sort_option);
                console.log('self.bet_base_list: %O', self.bet_base_list);
                console.log('self.bet_list: %O', self.bet_list);
            } else {
                self.is_data = false;
            }
            // 1回だけ更新（if内では呼ばない）
            self.update();
            self.event_register();
        } catch (error) {
            console.error('Error:', error);
        } finally {
            self._show_data_running = false;
        }

    }

    self.merge_shushi_data = function(myshushi_ary_sum, netkeirin_data_list, mode){
        var merge_data = {};
        if(myshushi_ary_sum[mode]){
            for(var date in myshushi_ary_sum[mode]){
                if(!merge_data[date]){
                    merge_data[date] = {};
                }
                merge_data[date] = myshushi_ary_sum[mode][date];
            }
        }
        if(mode == 'year'){
            mode = 'yearly';
        }
        if(netkeirin_data_list[mode]){
            for(var date in netkeirin_data_list[mode]){
                if(!merge_data[date]){
                    merge_data[date] = {};
                    merge_data[date]['total_bet_money'] = netkeirin_data_list[mode][date]['total_vote_money'];
                    merge_data[date]['total_pay'] = netkeirin_data_list[mode][date]['total_pay'];
                    merge_data[date]['total_diff'] = netkeirin_data_list[mode][date]['total_diff'];
                }else{
                    merge_data[date]['total_bet_money'] += netkeirin_data_list[mode][date]['total_vote_money'];
                    merge_data[date]['total_pay'] += netkeirin_data_list[mode][date]['total_pay'];
                    merge_data[date]['total_diff'] += netkeirin_data_list[mode][date]['total_diff'];
                }
            }
        }
        console.log('merge_data: %O', merge_data);
        return merge_data;
    }

    self.get_netkeirin_myshushi_sum_data = function(){
        return new Promise(function(resolve, reject) {
            var api_url = sprintf("%s/api/v1/analysis/balances", self.args.betapi_url);
            console.log('betapi_url: %s', api_url);
            var ndisam = new NDIsam();
            var key = sprintf("%s%s_%s_%s", self.args.ls_key_netkeirin, 'analysis', 'balances', self.args.sns_user_id);
            var list = ndisam.list(key);
            console.log('list: %O', list);
            var date = new Date() ;
            var now = date.getTime() ;
            now = Math.floor( now / 1000 ) ;
            if(list && now <= parseInt(list.shushi.date) + self.args.expire){
                console.log('get storege');
                resolve(list.shushi.data);
            }else{
                $.ajax({
                    type     : 'GET',
                    url: api_url,
                    dataType: 'json',
                    timeout: self.args.timeout_sec,
                    crossDomain: true, // 認証のためCookie設定
                    xhrFields: {
                        withCredentials: true // これを追加
                    },
                    success: function( result ){
                        resolve(result['data']);
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                        if(XMLHttpRequest.status == 404){
                            resolve({});
                        }
                        console.error('XMLHttpRequest.status: ',XMLHttpRequest.status)
                        console.error('textStatus: ',textStatus);
                        console.error('errorThrown.message: ',errorThrown.message);
                        resolve({});
                    }
                });
            }

        });
    }

    self.get_myshushi_data = function(){
        return new Promise(function(resolve, reject) {
            var add_param = {
                'compress': self.args.compress,
                'year' : self.year,
                'month' : self.month
            };
            $.ajax({
                type     : 'GET',
                url: self.args.api_url,
                data: add_param,
                dataType: 'json',
                timeout: self.args.timeout_sec,
                success: function( data ){
                    console.log('get http');
                    if(self.args.compress){
                        var z_stream = ZLIB.inflateInit();
                        var oj = z_stream.inflate( base64decode(data.ret) );
                        data.ret = JSON.parse(oj);
                    }
                    resolve(data.ret);
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.error('XMLHttpRequest.status: ',XMLHttpRequest.status)
                    console.error('textStatus: ',textStatus);
                    console.error('errorThrown.message: ',errorThrown.message);
                    reject({});
                }
            });
        });
    }

    self.get_netkeirin_myshushi_data = function(){
        console.log('self.current_date: %s', self.current_date);
        var string_date = String(self.current_date);
        var year = string_date.substr(0,4);
        var month = string_date.substr(4,2);
        var day = string_date.substr(6,2);

        return new Promise(function(resolve, reject) {
            var api_url = sprintf("%s/api/v1/analysis/balances/%s/%s/%s/votes", self.args.betapi_url, year, month, day);
            console.log('betapi_url: %s', api_url);
            $.ajax({
                type     : 'GET',
                url: api_url,
                dataType: 'json',
                timeout: self.args.timeout_sec,
                crossDomain: true, // 認証のためCookie設定
                xhrFields: {
                    withCredentials: true // これを追加
                },
                success: function( result ){
                    console.log('result: %O', result);
                    resolve(result['data']['votes']);
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    if(XMLHttpRequest.status == 404){
                        resolve({});
                    }
                    console.error('XMLHttpRequest.status: ',XMLHttpRequest.status)
                    console.error('textStatus: ',textStatus);
                    console.error('errorThrown.message: ',errorThrown.message);
                    resolve({});
                }
            });
            /*
            var ndisam = new NDIsam();
            var key = sprintf("%s%s%s%s_%s", self.args.ls_key_netkeirin, year, month, day, self.args.sns_user_id);
            var list = ndisam.list(key);
            console.log('list: %O', list);
            var date = new Date() ;
            var now = date.getTime() ;
            now = Math.floor( now / 1000 ) ;
            if(list && now <= parseInt(list.shushi.date) + self.args.expire){
                console.log('get storege');
                resolve(list.shushi.data.votes);
            }else{
                $.ajax({
                    type     : 'GET',
                    url: api_url,
                    dataType: 'json',
                    timeout: self.args.timeout_sec,
                    crossDomain: true, // 認証のためCookie設定
                    xhrFields: {
                        withCredentials: true // これを追加
                    },
                    success: function( result ){
                        result['date'] = now;
                        ndisam.replace(key, 'shushi', result);
                        resolve(result['data']['votes']);
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                        if(XMLHttpRequest.status == 404){
                            resolve({});
                        }
                        console.error('XMLHttpRequest.status: ',XMLHttpRequest.status)
                        console.error('textStatus: ',textStatus);
                        console.error('errorThrown.message: ',errorThrown.message);
                        resolve({});
                    }
                });
            }
*/
        });
    }

    //ソート
    self.act_sort = function(bet_list, sort_key, mode){
        console.log('bet_list: %O', bet_list);
        console.log('sort_key: %s', sort_key);
        var list = [];
        self.sort_type = {
            'sort_race' : '',
            'sort_hasso_time' : '',
            'sort_create_time' : '',
            'payback' : '',
        };
        var sort = {};
        for(race_id in bet_list){
            sort = {
                'sort': bet_list[race_id][sort_key],
                'detail': bet_list[race_id],
                'race_id': race_id
            };
            list.push(sort);
        }

        list.sort(function(a, b){
            if(mode == 'desc'){
                if (a.sort > b.sort) {
                    return -1;
                } else {
                    return 1;
                }
            }else{

                if (a.sort < b.sort) {
                    return -1;
                } else {
                    return 1;
                }
            }
        });
        if(mode == 'desc'){
            self.sort_type[sort_key] = 'asc';
        }else{
            self.sort_type[sort_key] = 'desc';
        }
        console.log('list: %O', list);
        // 発走順と、レース順の時のみ買い目もソートする
        if(sort_key == 'sort_hasso_time' || sort_key == 'sort_race'){
            console.log('list: %O', list);
            for(var i = 0; i < list.length; i++){
                list[i].detail.bet_list = self.sort_by_bet_item(list[i].detail.bet_list);
            }
        }else{
            for(var i = 0; i < list.length; i++){
                list[i].detail.bet_list.sort(function(a, b){
                    if(a.created_at < b.created_at){
                        return 1;
                    }else{
                        return -1;
                    }
                });
            }
        }
        return list;
    }

    /**
     * "YYYY/MM/DD HH:MM" → タイムスタンプ（ミリ秒）
     * @param {string} str
     * @returns {number} timestamp (ms)
     */
     self.toTimestamp = function(str) {
        console.log('str: %s', str);
        try {
            var [datePart, timePart] = str.split(" ");
            var [year, month, day] = datePart.split("-").map(Number);
            var [hour, minute] = timePart.split(":").map(Number);
            console.log('year: %s, month: %s, day: %s, hour: %s, minute: %s', year, month, day, hour, minute);
            var timestamp = new Date(year, month - 1, day, hour, minute).getTime();
            console.log('timestamp: %s', timestamp);
            // TIP連携のデータが秒なので、ミリ秒を秒に変換
            return timestamp / 1000;
        } catch (e) {
            return 0;
        }
    }

    self.sort_by_bet_item = function(rows){
        console.log('rows: %O', rows);
        const shikibetuOrder = [9, 8, 6, 5, 4, 3, 7];
        const houshikiPriority = [1, 2, 3, 4, 5, 6, 7, 8, 0];

        // true/false で分けて、同じロジックで並べて結合する
        var trues = rows.filter(function(r){
            return Boolean(r && r['is_netkeirin']) == true;
        });
        var falses = rows.filter(function(r){
            return Boolean(r && r['is_netkeirin']) === false;
        });

        const sortOneBucket = (bucketRows) => {
            const by = {};

            bucketRows.forEach(row => {
            if (!row || row.shikibetu == null || row.houshiki == null) return;

            const s = Number(row.shikibetu);
            const h = Number(row.houshiki);

            if (!by[s]) by[s] = {};
            if (!by[s][h]) by[s][h] = [];
            by[s][h].push(row); // 入力順維持
            });

            const result = [];

            shikibetuOrder.forEach(s => {
            if (!by[s]) return;

                houshikiPriority.forEach(h => {
                    if (!by[s][h]) return;

                    let items = [...by[s][h]];

                    // 通常（houshiki=0）のみ kaime1,2,3 昇順
                    //if (h === 0) {
                    items.sort((a, b) => {
                        const a1 = (a && a.kaime1 != null) ? String(a.kaime1) : '';
                        const b1 = (b && b.kaime1 != null) ? String(b.kaime1) : '';
                        const c1 = a1.localeCompare(b1);
                        if (c1 !== 0) return c1;

                        const a2 = (a && a.kaime2 != null) ? String(a.kaime2) : '';
                        const b2 = (b && b.kaime2 != null) ? String(b.kaime2) : '';
                        const c2 = a2.localeCompare(b2);
                        if (c2 !== 0) return c2;

                        const a3 = (a && a.kaime3 != null) ? String(a.kaime3) : '';
                        const b3 = (b && b.kaime3 != null) ? String(b.kaime3) : '';
                        return a3.localeCompare(b3);
                    });
                    //}

                    result.push(...items);
                });
            });

            return result;
        };

        return [...sortOneBucket(trues), ...sortOneBucket(falses)];

    }

    //制作
    self.event_register = function(){
        $('.Result_toggleInner').hide();
        $(document).off('click','.Balance_ListItem');
        $(document).on('click', '.Balance_ListItem' , function(){
            $(this).parents('.Balance_ListInner').next().stop().slideToggle('fast');
            $(this).find('.list_toggle').toggleClass('toggle_on');
        });
        $(document).off('click','.Balance_ListToggleItem .ListToggleItem_01');
        $(document).on('click', '.Balance_ListToggleItem .ListToggleItem_01' , function () {
            $(this).siblings('.ListToggleItem_03, .Develop_ToggleWrap').slideToggle('fast');
            $(this).find('.list_toggle').toggleClass('toggle_on');
        });
        $(document).off('click','.develop_toggle');
        $(document).on('click', '.develop_toggle', function () {
            $(this).next().stop().slideToggle('fast');
            $(this).toggleClass('toggle_on');
            if($(this).hasClass('toggle_on')){
                $(this).html('展開を閉じる<span></span>');
            } else {
                $(this).html('展開する<span></span>');
            }
            //if ($(this).attr() === '<a href="javascript:void(0)" class="develop_toggle">展開を閉じる<span></span></a>') {
            //    $(this).attr('<a href="javascript:void(0)" class="develop_toggle">展開する<span></span></a>');
            //} else {
            //    $(this).attr('<a href="javascript:void(0)" class="develop_toggle">展開を閉じる<span></span></a>');
            //};
        });
    }

    </script>

</daily>
