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_4';
extends 'App::bif';

sub run {
    my $self = shift;

    my $id;
    if ( my $str = $self->opts->{identity} ) {
        unless ( $str eq '-' ) {
            my $iinfo = $self->get_topic( $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 => [ 'wb.id AS id', 'wb.stop - wb.start AS delta', ],
            from   => 'work_buffers wb',
        ),
        select => [
            'wb.topic_id',
            q{strftime('%Y-%m-%d %H:%M:%S', }
              . q{ wb.gtime_start, 'unixepoch') AS start},
            q{wb.start_comment AS start_comment},
            q{strftime('%Y-%m-%d %H:%M:%S', }
              . q{ wb.gtime_stop, 'unixepoch') AS stop},
            q{wb.stop_comment AS stop_comment},
            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]', t.kind, t.id, t.path),'') AS path},
        ],
        from       => 'src',
        inner_join => 'work_buffers wb',
        on         => 'wb.id = src.id',
        left_join  => 'topics t',
        on         => 't.id = wb.topic_id',
        order_by   => 'wb.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 . 'Work:', $ref->{path} . $reset );
        $table->row( 'Start:',          $ref->{start} );
        $table->row( 'Stop:',           $ref->{stop} );
        $table->row( 'Delta:',          $ref->{delta} );
        $table->row( 'StartComment:',   $ref->{start_comment} )
          if $ref->{start_comment};
        $table->row( 'StopComment:', $ref->{stop_comment} )
          if $ref->{stop_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 $sth = $db->xprepare(
        with => 'worked',
        as   => sq(

            # Grab stuff from the work_buffers table
            select => [
                'wb.gtime_start AS start',
                q{strftime('%Y-%m-%d', }
                  . q{ wb.gtime_start, 'unixepoch') AS start_ymd},
                'wb.gtime_stop AS stop',
                'wb.stop - wb.start AS delta',
                't.id AS id',
                'i.shortname AS shortname',
                'COALESCE(t.path,"-") AS path',
                q{COALESCE(wb.start_comment || ', ' || wb.stop_comment,}
                  . q{wb.start_comment, wb.stop_comment, '-') AS comment},
                'wb.billable AS billable',
                case (
                    when => 'wb.billable != 1',
                    then => qv('-'),
                    else => qv(''),
                )->as('change_id'),
            ],
            from      => 'work_buffers wb',
            left_join => 'topics t',
            on        => 't.id = wb.topic_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',
                't.id AS id',
                'i.shortname AS shortname',
                't.path AS path',
                q{COALESCE(wd.start_comment || ', ' || wd.stop_comment,}
                  . q{wd.start_comment, wd.stop_comment, '-') AS comment},
                '1 AS billable',
                'wd.change_id AS change_id',
            ],
            from       => 'work_deltas wd',
            inner_join => 'topics t',
            on         => 't.id = wd.topic_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',
                '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.path AS path',
            'w.comment AS comment',
            'w.billable AS billable',
            'w.change_id AS change_id',
        ],
        from => 'worked w',

        # total/summary row
        union_all_select => [
            'ws.start_ymd AS start_ymd',
            '-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',
            'NULL AS path',
            'ws.day AS comment',
            'NULL AS billable',
            'NULL AS change_id',
        ],
        from     => 'worked_summary ws',
        order_by => [ 'start_ymd DESC', 'start ASC', 'stop ASC' ]
    );

    $sth->execute;
    $self->start_pager;

    my ( $yellow, $bold, $reset ) = $self->colours( 'yellow', 'bold', 'reset' );
    my $i     = 0;
    my $table = Text::FormatTable->new(' l  l  l  r  r ');
    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(' l  l  l  r  r ');
                $i     = 1;
            }
            elsif ($i) {
                $table->row( '-', '', '', '', '' );
            }

            if ( 0 == $ref->{comment} ) {
                $table->head(
                    $yellow . $ref->{start_ymd},
                    'Who', "Activity [today]",
                    'CID', $ref->{delta_hm} . $reset
                );
            }
            elsif ( 1 == $ref->{comment} ) {
                $table->head(
                    $yellow . $ref->{start_ymd},
                    'Who', "Activity [yesterday]",
                    'CID', $ref->{delta_hm} . $reset
                );
            }
            else {
                $table->head(
                    $yellow . $ref->{start_ymd},
                    'Who', "Activity [$ref->{comment} days ago]",
                    'CID', $ref->{delta_hm} . $reset
                );
            }
        }
        else {
            $table->row(
                ( $ref->{stop_hm} ? '' : $bold )
                . "$ref->{start_hm} - $ref->{stop_hm}",
                $ref->{shortname},
                "$ref->{comment} [$ref->{path}]",
                $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 #log

bif-wlog - review work buffer entries

=head1 VERSION

0.1.5_4 (2015-08-04)

=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.