#!/usr/bin/perl -w

use strict;
use Getopt::Long;
use Date::Manip;
use iCal::Parser;
use Text::Wrap;

my $start = undef;
my $end   = undef;

GetOptions(
 'start' => \$start,
 'end'   => \$end,
);

$start ||= UnixDate(ParseDate('last month'), '%Y-%m-01');
$end   ||= UnixDate(ParseDate('now'), '%Y-%m-01');

$start = ParseDate($start);
$end   = ParseDate($end);

my $filename = shift;

die "Please tell me a filename to work on!\n"
  unless defined $filename;
die "I can't find the file: $filename\n"
  unless -f $filename;

print "Processing date range: " . UnixDate($start, '%Y-%m-%d') . " - " . UnixDate($end, '%Y-%m-%d') . "\n\n";

my $parser = iCal::Parser->new(
  'start' => UnixDate($start, '%Y%m%d'),
  'end'   => UnixDate($end, '%Y%m%d'),
  'no_todos' => 1,
);

my $cal = $parser->parse($filename);
my $events = $cal->{'events'};

my %clients;
my %days;
my $total_hours = 0;

use Data::Dumper;
for my $year (keys %{ $events }) {
  for my $month (sort keys %{ $events->{$year} }) {
    for my $day (sort keys %{ $events->{$year}{$month} }) {
      for my $uid (keys %{ $events->{$year}{$month}{$day} }) {
        my $summary = $events->{$year}{$month}{$day}{$uid}{'SUMMARY'}     || '';
        my $desc    = $events->{$year}{$month}{$day}{$uid}{'DESCRIPTION'} || 'misc';
        my $hours   = $events->{$year}{$month}{$day}{$uid}{'hours'}       || 0;
        my $dtstart = $events->{$year}{$month}{$day}{$uid}{'DTSTART'}     || '';

        $hours = 8
          if defined $events->{$year}{$month}{$day}{$uid}{'allday'};

        $dtstart =~ s/T/ /;
        $desc =~ s/\\//g;

        $total_hours += $hours;

        # Days
        my ($day) = split(/ /, $dtstart);
        $days{$day}{lc($summary)}{'work'}{$desc} += $hours;
        $days{$day}{lc($summary)}{'client'} ||= $summary;

        # Clients
        $clients{lc($summary)}{'work'}{$desc}{'hours'} += $hours;
        $clients{lc($summary)}{'hours'} += $hours;
        $clients{lc($summary)}{'client'} ||= $summary;
        push @{ $clients{lc($summary)}{'work'}{$desc}{'times'} }, [ $hours, $dtstart ];
        #print "event: $summary - $dtstart - $desc\n";
      #print Dumper($entry);
      }
    }
  }
}

print_clients_summary();
print "\n";
print_clients();
print "\n";
print_days();

print "Total Hours Worked: $total_hours\n\n";

exit;

sub detail_line {
  my $indent = shift;
  return sprintf((' ' x $indent) . "%2.2f - %s\n", @_);
}
  
sub print_clients_summary {
  $Text::Wrap::columns = 78;
  for my $client (sort keys %clients) {
    print detail_line(2, $clients{$client}{'hours'}, $clients{$client}{'client'});
  }
}

sub print_clients {
  $Text::Wrap::columns = 78;
  for my $client (sort keys %clients) {
    print "$clients{$client}{'client'}:\n";
    print detail_line(2, $clients{$client}{'hours'}, 'Client Total');
    print "\n";
  
    for my $desc (sort keys %{ $clients{$client}{'work'} }) {
      print wrap('  ', '  ', $desc) . "\n";
  
      for my $time (sort { $a->[1] cmp $b->[1] } @{ $clients{$client}{'work'}{$desc}{'times'} }) {
        print detail_line(4, $time->[0], $time->[1]);
      }
  
      if (scalar(@{ $clients{$client}{'work'}{$desc}{'times'} }) > 1) {
        print detail_line(4, $clients{$client}{'work'}{$desc}{'hours'}, 'Total');
      }
    }

    print "\n";
  }
}

sub print_days {
  $Text::Wrap::columns = 70;
  for my $day (sort keys %days) {
    print "$day:\n";

    for my $client (sort keys %{ $days{$day} }) {
      for my $desc (sort keys %{ $days{$day}{$client}{'work'} }) {
        print detail_line(2, $days{$day}{$client}{'work'}{$desc}, wrap('', '         ', "$days{$day}{$client}{'client'} - $desc"));
      }
    }

    print "\n";
  }
}

