#!/usr/bin/env raku

use Tinky;
use Tinky::Declare;

class Ticket does Tinky::Object {
    has Str $.ticket-number = (^100000).pick.fmt("%08d");
    has Str $.owner;
}

my $workflow = workflow 'ticket-workflow', {
    initial-state 'new';
    workflow-state 'new';
    workflow-state 'open';
    workflow-transition 'open', 'new', 'open';

    workflow-state 'rejected' , {
        on-enter -> $object {
            say "** sending rejected e-mail for Ticket '{ $object.ticket-number }' **";
        }
    }

    workflow-transition 'reject', 'new', 'rejected';
    workflow-transition 'reject', 'open','rejected';
    workflow-transition 'reject', 'stalled','rejected';

    workflow-state 'in-progress';
    workflow-state 'stalled';

    workflow-transition 'stall', 'open', 'stalled';
    workflow-transition 'stall', 'in-progress', 'stalled', {
        on-apply-transition -> $object {
            say "** rescheduling tickets for '{ $object.owner }' on ticket stall **";
        }
    }

    workflow-state 'completed';

    workflow-transition 'unstall', 'stalled', 'in-progress';
    workflow-transition 'take', 'open', 'in-progress';
    workflow-transition 'complete', 'open', 'complete';
    workflow-transition 'complete', 'in-progress', 'complete';

    on-transition -> ( $transition, $object ) {
        say "Ticket '{ $object.ticket-number }' went from { $transition.from.name }' to '{ $transition.to.name }'";
    }

    on-final-state -> ( $state, $object) {
        say "** updating performance stats with Ticket '{ $object.ticket-number }' entered State '{ $state.name }'"
    }

};

my $ticket-a = Ticket.new(owner => "Operator A");

$ticket-a.apply-workflow($workflow);

$ticket-a.open;

$ticket-a.take;

$ticket-a.next-states>>.name.say;

$ticket-a.state = $workflow.state('stalled');

$ticket-a.reject;
