package Support::News::News;
use strict;

use lib '/app/tools/common/lib';
use lib '/app/tools/raptor/lib';
use lib '/app/tools/support/lib';
use Common::XMLObject;
use base 'Common::FormObject';

use Common::DB::Item::News;

use Common::UTF8;
use Common::Assert;
use Data::Dumper;

use Date::Format;
use Date::Parse;
use Date::Simple qw(today);

sub _init {
    my ( $self, %args ) = @_;

    if ( $args{dbItem} ) {
        $self->_initFromDBItem( $args{dbItem} );
    } elsif ( defined $args{newsID} ) {
        $self->_initFromID( $args{newsID} );
    } elsif ( defined $args{rssdata} ) {
        assert( $args{feedID}, "feedID required with rssdata" );
        $self->{FeedID} = $args{feedID};
        return unless ( $self->_initFromRSS( $args{rssdata} ) );
    }

    return $self;
}

sub _initFromID {
    my ( $self, $id ) = @_;

    my $dbItem = Common::DB::Item::News->Lookup( news_id => $id );
    return $self->_initFromDBItem($dbItem);
}

sub _initFromRSS {
    my ( $self, $rssdata ) = @_;
    my $properties = {};
    my $approved;
    my $keywordPattern;

    #Common::Log::Debug( "Pulling feed from: " . Dumper $rssdata );

    $properties->{url}         = $rssdata->{link};
    $properties->{feed_id}     = $self->{FeedID};
    $properties->{title}       = Common::UTF8::ToAscii( $rssdata->{title} );
    $properties->{description} = Common::UTF8::ToAscii( $rssdata->{description} );
    $properties->{category}    = Common::UTF8::ToAscii( $self->_categoryToString( $rssdata->{category} ) );

    # Strip out any HTML tags
    $properties->{title} =~ s/<(.+?)>//g;

    my $dateStr = $rssdata->{pubDate};
    my $date = str2time($dateStr) || time;
    $properties->{date_published} = time2str( "%Y-%m-%d %H:%M:%S", $date );

    if ( $keywordPattern = $self->_getKeywordPattern() ) {
        if ( $properties->{title} && $properties->{title} =~ /$keywordPattern/i ) {
            $approved = 1;
        } elsif ( $properties->{description} && $properties->{description} =~ /$keywordPattern/i ) {
            $approved = 1;
        } elsif ( $properties->{category} && $properties->{category} =~ /$keywordPattern/i ) {
            $approved = 1;
        }
    }

    # No keywords means approve everything.
    else {
        $approved = 1;
    }

    $properties->{approved} = $approved;

    $self->_initProperties($properties);

    return $self;
}

sub _initFromDBItem {
    my ( $self, $dbItem ) = @_;
    my $properties = {};

    foreach my $fieldName ( keys %$dbItem ) {
        next if '_' eq substr( $fieldName, 0, 1 );
        $properties->{$fieldName} = $dbItem->$fieldName;
    }

    $self->_initProperties($properties);
}

sub _initProperties {
    my $self       = shift;
    my $properties = shift;

    $self->{NewsID}        = $properties->{news_id};
    $self->{URL}           = $properties->{url};
    $self->{FeedID}        = $properties->{feed_id};
    $self->{Title}         = $properties->{title};
    $self->{Category}      = $properties->{category};
    $self->{Description}   = $properties->{description};
    $self->{Keyword}       = $properties->{keyword};
    $self->{Approved}      = $properties->{approved};
    $self->{DatePublished} = $properties->{date_published};
    $self->{DateCreated}   = $properties->{date_created};
}

sub setApproved {
    my ( $self, $flag ) = @_;
    my $newDBItem = Common::DB::Item::News->Lookup( news_id => $self->{NewsID} );
    $newDBItem->approved($flag);
    $newDBItem->save();
}

sub isDuplicate {
    my $self = shift;

    my $collection = Common::DB::Item::News->LookupByURL( $self->{URL} );

    return $collection->hasNext();
}

sub isExpired {
    my $self = shift;

    my $date = str2time( $self->{DatePublished} );
    my $expire = time - ( Common::DB::Item::News::kNewsDaysToExpire * 60 * 60 * 24 );

    return $date < $expire;

}

sub addToDB {
    my $self = shift;

    my $dbitem = Common::DB::Item::News->Create(
        url            => $self->{URL},
        feed_id        => $self->{FeedID},
        title          => $self->{Title},
        category       => $self->{Category},
        description    => $self->{Description},
        keyword        => $self->{Keyword},
        approved       => $self->{Approved},
        date_published => $self->{DatePublished}
    );

    $dbitem->save();
}

sub _categoryToString {
    my $self = shift;
    my $category = shift || return;
    my @result;

    # Ensure we are an array ref
    if ( ref($category) ne 'ARRAY' ) {
        $category = [$category];
    }

    foreach my $node (@$category) {
        next unless ($node);
        if ( !ref($node) ) {
            push( @result, $node );
        }

        elsif ( ref($node) eq 'HASH' ) {
            next unless ( keys %$node );

            #assert( $node->{content}, "missing category" );
            next unless ( $node->{content} );
            push( @result, $node->{content} );
        }

        else {
            die "I don't know how to handle you.";
        }
    }

    return @result ? join( ', ', @result ) : undef;
}

sub _getKeywordPattern {
    my $self = shift;

    my $feed = new Support::News::Feed( feedID => $self->{FeedID} );
    my $dbPattern = $feed->{Keywords};

    return unless ($dbPattern);

    #$pattern =~ s/\s*,\s*/|/g;

    my @patterns = split( ",", $dbPattern );
    foreach my $pattern (@patterns) {

        # Let's allow the plural version of the keywords to match.
        $pattern .= 's?';
    }

    $dbPattern = join( "|", @patterns );

    # We want to match on whole words only.
    #
    $dbPattern = '\b(' . $dbPattern . ')\b';

    return $dbPattern;
}

1;
