package Mojolicious::Plugin::CouchLiking;

use Mojo::Base 'Mojolicious::Plugin';
use Mojo::JSON;
use DBI;
use DBIx::CouchLike;
use DateTime qw();

sub register {
    my ($self, $app, $config) = @_;

    my $dbh = DBI->connect($config->{couch}->{dsn}, $config->{couch}->{user}, $config->{couch}->{pass});
    my $couch = DBIx::CouchLike->new({ dbh => $dbh, 
                                       table => $config->{couch}->{table}, 
                                       versioning => $config->{couch}->{versioning}, });

	print STDERR $config->{couch}->{dsn} . " NOT CONNECTED" if(!$dbh);
	print STDERR $config->{couch}->{dsn} . " NO COUCH" if(!$couch);
	#print STDERR $config->{couch}->{dsn} . " OK" if($dbh && $couch);

    # returns ALL eufui records, classified by date
    my $map_eufui = <<'END_OF_MAP';
sub {
  my ($obj, $emit) = @_;
  if($obj->{type} eq 'eufui'){
      $emit->($obj->{date} => 1);
  }
}
END_OF_MAP

    # returns UNmoderated eufui records, classified by date
    my $map_eufui_moderated = <<'END_OF_MAP';
sub {
  my ($obj, $emit) = @_;
  if($obj->{type} eq 'eufui' && $obj->{date_moderation} && $obj->{accepted}){
      $emit->($obj->{date} => 1);
  }
}
END_OF_MAP

    # returns moderated eufui records, classified by date
    my $map_eufui_pending = <<'END_OF_MAP';
sub {
  my ($obj, $emit) = @_;
  if($obj->{type} eq 'eufui' && !$obj->{date_moderation}){
      $emit->($obj->{date} => 1);
  }
}
END_OF_MAP

#     # optional reduce function
#     my $reduce_sub_str = <<'END_OF_REDUCE';
# sub {
#   my ($keys, $values) = @_;
#   return scalar @$values;
# }
# END_OF_REDUCE

    $couch->views_create({
          eufui => {
              map => $map_eufui,
              # reduce => $reduce_eufui,
          },
          eufui_moderated => {
              map => $map_eufui_moderated,
          },
          eufui_pending => {
              map => $map_eufui_pending, 
          }},
          1);

    # creates a record
    # my $testpage = {
    #     path => 'TestPage',
    #     type   => 'test_page',
    #     active => 'true',
    # };
    # $couch->put($testpage);

    # accesses a record
    # my $itr;
    # my $user;
    # $itr = $app->couch->view('site/user',{ key => $username, include_docs => 1 });
    # $user = $itr->next;
    # return $user->{document};

    $app->helper( couch => sub { $couch; } );

    # returns array of moderated or UNmoderated ($pending=1) eufui records, classified by date
    # uses view: eufui (moderated) or eufui_pending (UNmoderated)
    $app->helper( eufui => sub {
      my $self = shift;
      my ($pending) = @_;
      my @result = ();
      my $itr;
      my $rec;
      $itr = $couch->view(($pending ? 'eufui_pending':'eufui_moderated'),{ include_docs => 1 });
      while (1) {
        $rec = $itr->next;
        last if(!$rec);
        push @result, $rec->{document}; 
      }
      return \@result;
    });

    # updates an eufui record identified its id, setting its fields:
    # - moderator = email address of moderator
    # - date_moderation = current local time (or second argument if set)
    $app->helper( eufui_moderate => sub {
      my $self = shift;
      my ($urlkey, $accept, $moderator, $date_moderation) = @_;
      my $resultmsg = '';
      if(!$date_moderation){
        $date_moderation = datetimefordb();
      }
      my $itr;
      my $rec;
      $itr = $couch->view('eufui',{ include_docs => 1 });
      while (1) {
        $rec = $itr->next;
        if(!$rec){
          $resultmsg = 'Erro - eufui não existe';
          last;
        }
        if($rec->{document}->{urlkey} eq $urlkey){
          # moderates, updating the eufui record in function of the accept parameter
          $rec->{document}->{accepted} = $accept;
          $rec->{document}->{moderator} = $moderator;
          $rec->{document}->{date_moderation} = $date_moderation;
          $couch->put($rec->{document});
          $resultmsg = 'Eufui ' . ($accept ? 'aceitado':'rejeitado') . ' por ' . $moderator;
          last;
        }
      }
      return $resultmsg;
    });

    # returns the full db record of an eufui as a string (JSON encoded)
    $app->helper( eufui_json => sub {
      my $self = shift;
      my ($urlkey) = @_;
      my $itr;
      my $rec;
      $itr = $couch->view('eufui',{ include_docs => 1 });
      while (1) {
        $rec = $itr->next;
        if(!$rec){
          return '';
        }
        if($rec->{document}->{urlkey} eq $urlkey){
          return $couch->to_json($rec->{document});
        }
      }
    });

    # creates the eufui record, unmoderated (date_moderation and moderator fields undefined)
    $app->helper( eufui_create => sub {
      my $self = shift;
      my ($uploads, $ip, $sessionid, $name, $email, $city, $message, $modurlkey) = @_;
      my $eufui_record = {
        type => 'eufui',
        date => datetimefordb(),
        fotos => $uploads,
        requestip => $ip,
        sessionid => $sessionid,
        formname => $name,
        formemail => $email,
        formcity => $city,
        formmessage => $message,
        urlkey => $modurlkey,
        accepted => 0,
        date_moderation => '',
        moderator => '',
      };
      my $eufui_id = $couch->put($eufui_record);
      return $eufui_id;
    });

    $app->helper( contato_create => sub {
      my $self = shift;
      my ($ip, $sessionid, $name, $email, $message) = @_;
      my $contato_record = {
        type => 'contato',
        date => datetimefordb(),
        requestip => $ip,
        sessionid => $sessionid,
        formname => $name,
        formemail => $email,
        formmessage => $message,
      };
      my $contato_id = $couch->put($contato_record);
      return $contato_id;
    });
}

sub datetimefordb {
  my $datetimeobj = shift || DateTime->now;
  return $datetimeobj->strftime('%Y%m%d %H:%M:%S');
}

1;
