package Local::Class::DBI::Relationship::Extends;

use strict;
use warnings;

use base 'Local::Class::DBI::Relationship::HasA';


sub remap_arguments {
	my ($proto, $class, $want_col, $f_class) = @_;  

	my $column = $class->find_column($want_col)
		or return $class->_croak("Column $want_col does not exist in $class");

	$class->_require_class($f_class);

	$class->add_searcher(search_extended => q(Local::Class::DBI::Search::Extended));

	my %import_column = map +($_ => $_), $f_class->columns();
	delete $import_column{$_} for $f_class->columns(q(Primary));

	{
	  no strict 'refs';
	  *{"$class\::insert"} = sub {
	    my ($class, $data)  = @_;
	    my @parent_keys = keys %import_column;
	    my %parent_object;
	    @parent_object{@parent_keys} = delete @$data{@parent_keys};
#	    warn Data::Dumper::Dumper($class->meta_info);
	    my $parent_column = $f_class->primary_column;
	    $data->{$parent_column} = $f_class->insert(\%parent_object) unless (defined $data->{$parent_column});
	    return Local::Class::DBI::insert($class,$data);
	  };
	}

	return ($class, $column, $f_class, { import => [ keys %import_column ], key => $f_class->primary_column});
}

sub triggers {
	my $self = shift;

	my %triggers = $self->SUPER::triggers();

	my $method = $self->accessor;
	$triggers{'before_update'} = sub { if (my $for_obj = shift->$method()) { $for_obj->update } };

	return %triggers;
}

sub methods {
	my $self = shift;
	my ($class, $method) = ($self->class, $self->accessor);
	return (
		map { $_ => $self->_imported_accessor($_) } @{$self->args->{import}} 
	);
}

sub _imported_accessor {
	my ($rel, $name) = @_;
	my ($class, $method) = ($rel->class, $rel->accessor);
	return sub {
		my $self = shift;
		my $meta = $class->meta_info($rel->name => $method);
		my ($f_class, @extra) =
			($meta->foreign_class, @{ $meta->args->{import} });

		# Might need to flesh out $method
		unless (ref($self->$method())) {
		  $self->_flesh($self->__grouper->groups_for($method));
		}

		my $for_obj = $self->$method() || do {
			return unless @_;    # just fetching
			my $val = shift;
			$f_class->insert(
				{ $f_class->primary_column => $self->id, $name => $val });
			$self->$method();
		};
		$for_obj->$name(@_);
	};
}

1;
