package WebService::Strava::Athlete::Activity;

use v5.010;
use strict;
use warnings;
use Scalar::Util qw(looks_like_number);
use Carp qw(croak);
use Scalar::Util::Reftype;
use Data::Dumper;
use Method::Signatures 20140224;
use Moo;
use experimental 'switch';
use namespace::clean;

# ABSTRACT: A Strava Activity Object

our $VERSION = '0.06'; # VERSION: Generated by DZP::OurPkg:Version


# Validation functions

my $Ref = sub {
  croak "auth isn't a 'WebService::Strava::Auth' object!" unless reftype( $_[0] )->class eq "WebService::Strava::Auth";
};

my $Bool = sub {
  croak "$_[0] must be 0|1" unless $_[0] =~ /^[01]$/;
};

my $Num = sub {
  croak "$_[0] isn't a valid id" unless looks_like_number $_[0];
};

# Debugging hooks in case things go weird. (Thanks @pjf)

around BUILDARGS => sub {
  my $orig  = shift;
  my $class = shift;
  
  if ($WebService::Strava::DEBUG) {
    warn "Building task with:\n";
    warn Dumper(\@_), "\n";
  }
  
  return $class->$orig(@_);
};

# Authentication Object
has 'auth'            => ( is => 'ro', required => 1, isa => $Ref );

# Defaults + Required
has 'id'                      => ( is => 'ro', required => 1, isa => $Num);
has '_build'                  => ( is => 'ro', default => sub { 1 }, isa => $Bool );

# Segment Effort
has 'name'                      => ( is => 'ro', lazy => 1, builder => '_build_activity' );

has 'resource_state'            => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'indicates_level_of_detail' => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'external_id'               => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'provided_at_upload'        => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'athlete'                   => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'description'               => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'distance'                  => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'moving_time'               => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'elapsed_time'              => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'total_elevation_gain'      => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'type'                      => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'start_date'                => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'start_date_local'          => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'time_zone'                 => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'start_latlng'              => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'end_latlng'                => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'location_city'             => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'location_state'            => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'location_country'          => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'achievement_count'         => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'kudos_count'               => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'comment_count'             => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'athlete_count'             => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'photo_count'               => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'map'                       => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'trainer'                   => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'commute'                   => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'manual'                    => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'private'                   => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'flagged'                   => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'workout_type'              => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'gear_id'                   => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'gear'                      => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'average_speed'             => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'meters_per_second'         => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'max_speed'                 => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'average_cadence'           => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'average_temp'              => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'average_watts'             => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'kilojoules'                => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'average_heartrate'         => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'max_heartrate'             => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'calories'                  => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'truncated'                 => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'has_kudoed'                => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'segment_efforts'           => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'splits_metric'             => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'splits_standard'           => ( is => 'ro', lazy => 1, builder => '_build_activity' ); 
has 'best_efforts'              => ( is => 'ro', lazy => 1, builder => '_build_activity' );
 
sub BUILD {
  my $self = shift;

  if ($self->{_build}) {
    $self->_build_activity();
  }
  return;
}

method _build_activity() {
  my $activity = $self->auth->get_api("/activities/$self->{id}");
  $self->_init_from_api($activity);
  return;
}

method _init_from_api($activity) {
  foreach my $key (keys %{ $activity }) {
    given ( $key ) {
      when      ("athlete")           { $self->_instantiate("Athlete", $key, $activity->{$key}); }
      when      (/segment_efforts/)   { $self->_instantiate("Athlete::Segment_Effort", $key, $activity->{$key}); }
      default                         { $self->{$key} = $activity->{$key}; }
    }
  }

  return;
}

use WebService::Strava::Athlete;
use WebService::Strava::Athlete::Segment_Effort;

method _instantiate($type, $key, $data) {
  if (ref($data) eq "ARRAY") {
    my $index = 0;
    foreach my $item (@{$data}) {
      @{$data}[$index] = "WebService::Strava::$type"->new(auth => $self->auth, id => $item->{id}, _build => 0);
      $index++;
    }
    $self->{$key} = $data;
  } else {
    $self->{$key} = "WebService::Strava::$type"->new(auth => $self->auth, id => $data->{id}, _build => 0);
  }
  return;
}


method retrieve() {
  $self->_build_activity();
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

WebService::Strava::Athlete::Activity - A Strava Activity Object

=head1 VERSION

version 0.06

=head1 SYNOPSIS

  my $activity = WebService::Strava::Athlete::Activity->new( auth => $auth, id => '229781' );

=head1 DESCRIPTION

  Upon instantiation will retrieve the activity matching the id.
  Requires a pre-authenticated WebService::Strava::Auth object.

=head1 METHODS

=head2 retrieve()

  $activity->retrieve();

When a Activity object and is lazy loaded, you can call retrieve it by calling
this method.

=head1 AUTHOR

Leon Wright < techman@cpan.org >

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by Leon Wright.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
