Definition: [
    "autonomous agent",
    {
        "bounce_fees": {
            "base": 10000
        },
        "init": "{
        $DAY = 86400;
        $PURCHASE_PERIOD = 1 * $DAY;
        $PAYOUT_PERIOD = 1 * $DAY;
        $PRICE = 1000; // bytes per ticket
        $CONTROL_ADDRESS = 'T7BTEFK6V6GBD3XLFTCZVBZTS4HS7R7Q';
        $round = var['round'] otherwise 0;
        $asset = var[$round || '-asset'];
        $enddate = var[$round || '-enddate'] otherwise 0;
        $tickets = var[$round || '-tickets'] otherwise 0;
        $open = timestamp < $enddate;
        $hours_till_next_round = max(0, round(($enddate + $PAYOUT_PERIOD - timestamp) / 3600, 2));
        $player = $round || '-' || trigger.address;
        $winner = var[$round || '-winner'];
        $prize = var[$round || '-prize'];
        $lo = var[$player || '-lo'] otherwise 0;
        $hi = var[$player || '-hi'] otherwise 0;
    }",
        "messages": {
            "cases": [
                {
                    "if": "{ trigger.data.update AND trigger.address == $CONTROL_ADDRESS}",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{trigger.address}",
                                        "amount": "{ trigger.data.sweep ? "": trigger.output[[asset='base']] - 1000 }"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            if (trigger.data.enddate) {
                                var[$round || '-enddate'] = trigger.data.enddate;
                                response[$round || '-enddate'] = trigger.data.enddate;
                            }
                        }"
                        }
                    ]
                },
                {
                    "if": "{ trigger.data.query }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{trigger.address}",
                                        "amount": "{ trigger.output[[asset='base']] - 1000 }"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            response['round'] = $round;
                            response['open'] = $open;
                            response['asset'] = $asset;
                            response['enddate'] = $enddate;
                            response['payout_enddate'] = $enddate + $PAYOUT_PERIOD;
                            response['message'] = 'Round #' || $round || ' is currently '
                                || ($open
                                    ? 'open with accumulated balance of ' || balance[base]
                                    : 'closed. The final prize is ' || $prize );
                        }"
                        }
                    ]
                },
                {
                    "if": "{ trigger.data.open }",
                    "init": "{
                    if (timestamp < $enddate + $PAYOUT_PERIOD) {
                        bounce("Lottery ticket for round #" || $round || ' has already been created. Next round is possible in ' || $hours_till_next_round || ' hours');
                    }
                }",
                    "messages": [
                        {
                            "app": "asset",
                            "payload": {
                                "is_private": false,
                                "is_transferrable": true,
                                "auto_destroy": true,
                                "fixed_denominations": false,
                                "issued_by_definer_only": true,
                                "cosigned_by_definer": false,
                                "spender_attested": false
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            $new_round = $round + 1;
                            $new_enddate = timestamp + $PURCHASE_PERIOD;
                            var['round'] = $new_round;
                            var[$new_round || '-enddate'] = $new_enddate;
                            var[$new_round || '-asset'] = response_unit;
                            
                            response['round'] = $new_round;
                            response['enddate'] = $new_enddate;
                            response['asset'] = response_unit;
                            response['message'] = 'New lottery round ' || $new_round || ' created.';
                        }"
                        }
                    ]
                },
                {
                    "if": "{ trigger.data.close }",
                    "init": "{
                    if (!$round) bounce('Lottery has not started yet.');
                    if (!$tickets) bounce("No tickets were sold in this round.");
                    if ($open) bounce("Lottery is still open. Wait until the purchase period expires!");
                    if ($winner) bounce("The lottery is already closed and the winner has been selected.");
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            $seed = mc_unit;
                            var[$round || '-seed'] = $seed; 
                            var[$round || '-winner'] = $tickets == 1 ? 1 : number_from_seed($seed, $tickets - 1) + 1;
                            var[$round || '-prize'] = balance['base'];
                        }"
                        }
                    ]
                },
                {
                    "if": "{ $winner AND trigger.output[[asset=$asset]] > 0 }",
                    "init": "{
                    $reimbursement = trigger.output[[asset='base']] - 1000;
                    if ($lo <= $winner AND $winner <= $hi) {
                        $amount = $reimbursement + $prize;
                    } else {
                        $amount = $reimbursement;
                    }
                }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{trigger.address}",
                                        "amount": "{ $amount }"
                                    }
                                ]
                            }
                        }
                    ]
                },
                {
                    "init": "{
                    if (!$asset) bounce("Lottery tickets are not available yet");
                    if (!$open) bounce("Lottery round has closed.");
                    if ($lo OR $hi) bounce("You already bought tickets in this round. Come back in the next round!");
                    $amount = round(trigger.output[[asset=base]] / $PRICE);
                }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "{$asset}",
                                "outputs": [
                                    {
                                        "address": "{trigger.address}",
                                        "amount": "{$amount}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            var[$player || '-lo'] = $tickets + 1;
                            var[$player || '-hi'] = $tickets + $amount;
                            var[$round || '-tickets'] += $amount;
                            response['message'] = 'You purchased ' || $amount || ' tickets of ' || $asset || ' in round #' || $round || '. The first ticket number is ' || $tickets + 1 || ', the last is ' || $tickets + $amount;
                        }"
                        }
                    ]
                }
            ]
        }
    }
]