package DBIx::Class::ResultSet::WithMetaData;

use strict;
use warnings;

use Data::Alias;
use Moose;
use MooseX::Method::Signatures;
extends 'DBIx::Class::ResultSet';

has '_row_info' => (
	is => 'rw',
	isa => 'HashRef'
);

has 'was_row' => (
	is => 'rw',
	isa => 'Int'
);

has 'id_cols' => (
	is => 'rw',
	isa => 'ArrayRef',
);
	

sub new {
	my $self = shift;

	my $new = $self->next::method(@_);
	foreach my $key (qw/_row_info was_row id_cols/) {
		alias $new->{$key} = $new->{attrs}{$key};
	}

	unless ($new->_row_info) {
		$new->_row_info({});
	}

	unless ($new->id_cols && scalar(@{$new->id_cols})) {
		$new->id_cols([sort $new->result_source->primary_columns]);
	}

	return $new;
}

method display () {
  my $rs = $self->search({});
  $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
  my @rows;
	foreach my $row ($rs->all) {
		if (my $info = $self->row_info_for(id => $self->_mk_id(row => $row))) {
			$row = { %{$row}, %{$info} };
		}
		push(@rows, $row);
	}

  return ($self->was_row) ? $rows[0] : \@rows;
}

method add_row_info (Int :$id, :$row, HashRef :$info) {
	if ($row) {
		$id = $self->_mk_id(row => { $row->get_columns });
	}
	unless ($self->find($id)) {
		warn $id;
		die 'invalid id passed to add_row_info';
	}

	if (my $existing = $self->_row_info->{$id}) {
		$info = { %{$existing}, %{$info} };
	}

	$self->_row_info->{$id} = $info;	
}

method row_info_for (Int :$id) {
	return $self->_row_info->{$id};
}

method order_by (Str :$col) {
	$col = "me.$col" unless ($col =~ m/\./);
	return $self->search({}, { order_by => $col });
}

method limit (Int :$count) {
	return $self->search({}, { rows => $count });
}

method with_token {
	foreach my $row ($self->all) {
		my $token = $self->tokenify($row->get_column($self->token_col));
		$self->add_row_info(id => $row->id, info => { join('_', 'token', $self->token_col) => $token });
	}

	return $self;
}

method _mk_id (HashRef :$row) {
	return join('-', map { $row->{$_} } @{$self->id_cols});
}
	

sub tokenify {
  my ($self, $string) = @_;

  $string =~ s/\s+$//;
  $string =~ s/[,\.\-\+]//g;
  $string =~ s/^\s+//;
  $string =~ s/ /-/g;
  $string = lc($string);
  return $string;
}

sub clean_rs {
  my $self = shift;

  return $self->result_source->resultset;
}

1;
