package App::bif::wlog;
use strict;
use warnings;
use utf8;
use Bif::Mo;
use DBIx::ThinSQL qw/case coalesce sq qv/;
use Text::FormatTable;

our $VERSION = '0.1.5_7';
extends 'App::bif';

sub run {
    my $self = shift;

    my $id;
    if ( my $str = $self->opts->{identity} ) {
        unless ( $str eq '-' ) {
            my $iinfo = $self->get_node( $str, 'identity' );
            $id = $iinfo->{id};
        }
    }
    else {
        $id = $self->db->xval(
            select => 'b.identity_id',
            from   => 'bifkv b',
            where  => { key => 'self' },
        );
    }

    return $self->work_log_long($id) if $self->opts->{long};
    return $self->work_log_short($id);
}

sub work_log_long {
    my $self        = shift;
    my $identity_id = shift;
    my $db          = $self->db;

    my $sth = $db->xprepare(
        with => 'src',
        as   => sq(
            select => [ 'wd.id AS id', 'wd.stop - wd.start AS delta', ],
            from   => 'work_deltas wd',
        ),
        select => [
            'c.action AS action',
            'wd.node_id',
            q{strftime('%Y-%m-%d %H:%M:%S', }
              . q{ wd.gtime_start, 'unixepoch') AS start},
            q{wd.comment AS comment},
            q{strftime('%Y-%m-%d %H:%M:%S', }
              . q{ wd.gtime_stop, 'unixepoch') AS stop},
            q{ printf('%+0.2d:%0.2d:%0.2d', }
              . q{ src.delta / 3600, }
              . q{ (src.delta - 3600 * (src.delta / 3600)) / 60, }
              . q{ src.delta % 60 ) AS delta},
            q{COALESCE(printf('%s %s [%s]', n.kind, n.id, n.path),'') AS path},
        ],
        from       => 'src',
        inner_join => 'work_deltas wd',
        on         => 'wd.id = src.id',
        inner_join => 'changes c',
        on         => 'c.id = wd.change_id',
        left_join  => 'nodes n',
        on         => 'n.id = wd.node_id',
        order_by   => 'wd.id DESC',
    );
    $sth->execute;

    my ( $yellow, $bold, $reset ) = $self->colours( 'yellow', 'bold', 'reset' );

    $self->start_pager;

    while ( my $ref = $sth->hashref ) {
        my $table = Text::FormatTable->new(' l  l');

        $table->row( $yellow . 'Action:', $ref->{action} . $reset );
        $table->row( 'Start:',            $ref->{start} );
        $table->row( 'Stop:',             $ref->{stop} );
        $table->row( 'Delta:',            $ref->{delta} );
        $table->row( 'Comment:',          $ref->{comment} )
          if $ref->{comment};

        print $table->render, "\n";
    }

    return $self->ok('WorkLogLong');
}

sub work_log_short {
    my $self        = shift;
    my $identity_id = shift;
    my $db          = $self->db;
    my ( $yellow, $bold, $reset ) = $self->colours( 'yellow', 'bold', 'reset' );

    my $sth = $db->xprepare(
        with => 'worked',
        as   => sq(

            # Grab stuff from the work_buffers table
            select => [
                'wb.start + wb.offset AS start',
                q{strftime('%Y-%m-%d', }
                  . q{ wb.start+wb.offset, 'unixepoch') AS start_ymd},
                "strftime('%s','now') AS stop",
                "strftime('%s','now') - wb.start AS delta",
                'n.id AS id',
                'i.shortname AS shortname',
                "'work ' || n.kind || ' ' || n.path "
                  . "|| COALESCE(' -- '|| wb.comment, '') AS action",
                'wb.bill AS bill',
                "'-' AS change_id",
            ],
            from       => 'work_buffers wb',
            inner_join => 'nodes n',
            on         => 'n.id = wb.node_id',
            $identity_id
            ? (
                inner_join => 'identities i',
                on         => { 'i.id' => $identity_id },
              )
            : (
                inner_join => 'bifkv b',
                on         => { 'b.key' => 'self', },
                inner_join => 'identities i',
                on         => 'i.id = b.identity_id',
            ),

            # Grab stuff from the work_deltas table
            union_all_select => [
                'wd.gtime_start AS start',
                q{strftime('%Y-%m-%d', }
                  . q{ wd.gtime_start, 'unixepoch') AS start_ymd},
                'wd.gtime_stop AS stop',
                'wd.stop - wd.start AS delta',
                'n.id AS id',
                'i.shortname AS shortname',
                "c.action || COALESCE(' -- '|| wd.comment, '') AS action",
                '0 AS bill',
                'wd.change_id AS change_id',
            ],
            from       => 'work_deltas wd',
            inner_join => 'nodes n',
            on         => 'n.id = wd.node_id',
            inner_join => 'changes c',
            on         => {
                'c.id' => \'wd.change_id',
                $identity_id ? ( 'c.identity_id' => $identity_id, ) : (),
            },
            inner_join => 'identities i',
            on         => 'i.id = c.identity_id',
        ),

        # Sum the above grouped by day
        ',' => 'worked_summary',
        as  => sq(
            select => [
                'w.start_ymd AS start_ymd',
                'MAX(w.start) AS max_start',
                'SUM(w.delta) AS delta',
                "julianday(date('now','localtime'))"
                  . " - julianday(w.start_ymd) AS day"
            ],
            from     => 'worked w',
            group_by => [ 'start_ymd', 'day' ],
        ),

        # Now format all of that nicely
        select => [
            'w.start_ymd AS start_ymd',
            'w.start AS start',
            "strftime('%H:%M', w.start, 'unixepoch') AS start_hm",
            'w.stop AS stop',
            "COALESCE(strftime('%H:%M', w.stop, 'unixepoch'),"
              . "'') AS stop_hm",
            q{ printf('%+0.2d:%0.2d', }
              . q{ round(w.delta / 3600), }
              . q{ (w.delta - 3600 * round(w.delta / 3600)) / 60)
              AS delta_hm },
            'w.shortname AS shortname',
            'w.id AS id',
            'w.action AS action',
            'w.bill AS bill',
            'w.change_id AS change_id',
        ],
        from => 'worked w',

        # total/summary row
        union_all_select => [
            'ws.start_ymd AS start_ymd',
            'ws.max_start + 1 AS start',
            '-1 AS start_hm',
            '-1 AS stop',
            '-1 AS stop_hm',
            q{ printf('%+0.2d:%0.2d', }
              . q{ round(ws.delta / 3600), }
              . q{ (ws.delta -}
              . q{ 3600 * round(ws.delta / 3600)) / 60) AS delta_hm},
            '-1 AS shortname',
            'NULL AS id',
            'ws.day AS action',
            'NULL AS bill',
            'NULL AS change_id',
        ],
        from     => 'worked_summary ws',
        order_by => [ 'start_ymd DESC', 'start DESC', 'stop DESC' ]
    );

    $sth->execute;

    #    $sth->dump_results;
    $self->start_pager;

    my $i      = 0;
    my $format = ' l  l  l  r ';
    my @empty  = ( '-', '', '', '' );
    my $table  = Text::FormatTable->new($format);
    my $first  = 1;

    while ( my $ref = $sth->hashref ) {

        if ( $ref->{start_hm} eq '-1' ) {

            # Every 200 rows or so spit out the table and start again.
            if ( $i > 200 ) {
                print $table->render( $self->term_width ), "\n";
                $table = Text::FormatTable->new($format);
                $i     = 1;
            }
            elsif ($i) {
                $table->row(@empty);
            }

            $table->head(
                $yellow . $ref->{start_ymd},
                0 == $ref->{action}   ? 'Activity [today]'
                : 1 == $ref->{action} ? 'Activity [yesterday]'
                : "Activity [$ref->{action} days ago]",
                'CID',
                $ref->{delta_hm} . $reset
            );

        }
        else {
            $table->row(
                ( $ref->{change_id} eq '-' ? $bold : '' )
                . "$ref->{start_hm} - $ref->{stop_hm}",
                $ref->{action},
                $ref->{change_id},
                $ref->{delta_hm} . $reset,

            );
        }

        $i++;
    }

    print $table->render( $self->term_width ), "\n";

    return $self->ok('WorkLogShort');
}

1;
__END__

=head1 NAME

=for bif-doc #timesheet

bif-wlog - review work buffer entries

=head1 VERSION

0.1.5_7 (2015-11-25)

=head1 SYNOPSIS

    bif wlog [OPTIONS...]

=head1 DESCRIPTION

The B<bif-wlog> command prints the entries in the work buffer that have
been created with the L<bif-work> command.

=head1 OPTIONS

=over

=item --identity, -i IDENTITY_ID

Limit work buffer/delta items displayed to those created by
IDENTITY_ID. Use "-" to see all identity work deltas.

=item --long, -l

Display a multiple-line email-style version of each work buffer entry.

=back

=head1 SEE ALSO

L<bif-work>

=head1 AUTHOR

Mark Lawrence E<lt>nomad@null.netE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright 2015 Mark Lawrence <nomad@null.net>

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

