#!/usr/bin/perl

#use utf8;
use strict;
use CGI;

use POSIX qw(
    ceil
    floor
);
use Opals::Context;#use MARC::File::USMARC;
use Opals::MarcXmlParser;
use Opals::RecordInfoHTML qw(
    rinfo_getPageNavForm_search
);

use Opals::SolrIndex qw(
    slr_search
    slr_buildSearchQuery
    slr_buildSearchQuery_ARL
    slr_getSuggestion
    slr_updateIndexDir
    slr_updateIndexFile
    slr_delIndex
    slr_browseSubject_beginWith
    slr_browseSubject_keyword
    slr_browseAuthor_keyword
    
);
use Opals::BookCover qw(
    bookCover_getUrl
);
use Opals::Marc21 qw(
    mc21_infoGeneral
);

use Opals::Template qw(
    tmpl_read
    tmpl_write
    tmpl_preference
    tmpl_rangedPageList
    tmpl_getSearchFieldList
);
use Opals::Search qw(
    srch_searchRecord
    srch_buildPQF
    srch_zTab
    srch_buildNewItemSQLs
    srch_searchRecordSQL
    srch_zDatabase
);
use Opals::Portal qw(
    portal_getNewItemList
);
use Opals::Rating qw(
    cmntRating_getAvgRating
    cmntRating_numOfRating
);

use Opals::WebServiceClient qw(
    wsc_getCircData
);
use Opals::Locale qw(
    loc_getMsgFile
    loc_write
);
    my $dbh = Opals::Context->dbh();
    my $cgi     = CGI->new;
    my $input = $cgi->Vars();
    END { $dbh->disconnect(); }

my ($permission, $cookie, $template) = tmpl_read(
        {
            dbh             => $dbh,
            cgi             => $cgi,
            tmplFile        => 'search/searchPage.tmpl',
        }
);
my $msgValMap={} ;

my @cookieList = (@$cookie);

my  $lang = $cgi->cookie('language');
if($lang !~ m/en|fr/i){
    $lang          = 'en';
}

my $iCount = 0;
my $pref = tmpl_preference($dbh);
my $multilingual            = $pref->{'multilingual'};
my $link1_name            = $pref->{'link1_name'};
my $link1_url             = $pref->{'link1_url'};
my $link2_name            = $pref->{'link2_name'};
my $link2_url            = $pref->{'link2_url'};
my $formatMsgMap  =loc_getMsgFile('search/facet.msg',{});


$template->param(
        link1_name=>$link1_name ,
        link1_url =>$link1_url ,
        link2_name=>$link2_name , 
        link2_url =>$link2_url , 
   );
   
    writeSortParam2tmpl($input);
    # searchfilter fields
    setSearchFormFilter();
    #setPageNavForm($cgi);
    my $pageNavForm =rinfo_getPageNavForm_search($cgi);
    $template->param(pageNavForm=>$pageNavForm,
                     );

    my $zid = $input->{'zid'};
    ($zid && $zid =~ m/^[\d]+$/ && $zid >= 0) || ($zid = 0);

     
 #---------------------- SEARCH --------------------
    my  $showLocation =Opals::Context->preference('showLocation');


    my $pSize   = 10;
    my $curPage = $input->{'pNum'};
    ($curPage && $curPage >= 1) || ($curPage = 1);
    my $offset      = ($curPage - 1) * $pSize ;
    my $sortAttr    = $input->{'sortAttr'};
    my $sortOrder   = $input->{'sortOrder'};
    my $rs=undef;
#   search for local database
    if($zid == 0){
        $rs = search_localDb();
    }
    else{
        $rs= search_z3950();
    }
    my ($hits,$recList) = ($rs->{'hits'},$rs->{'recordList'});
    if($hits >0){
        getBookCover($recList);
        getRating($recList);
        if ($hits - $offset + 1 <= 0) {
            my $availRange = $hits % $pSize;
            $availRange = $pSize if ($availRange == 0); 
            $offset = $hits - $availRange + 1;
            $curPage = ($offset - 1) / $pSize + 1;
        }
        my $recRsPos =$offset;                
        my $bkShelfMidCallno="";
        my $bkShelfMidRecId=0;
        foreach my $rec(@$recList){
            $rec->{'callnumber'} =~ s/[\s]+/<br>/g; 
            $rec->{'recRsPos'}=$recRsPos++; 
            
                
            if($bkShelfMidCallno eq '' && $rec->{'callNum1St'} ne '' ){
                $bkShelfMidCallno = $rec->{'callNum1St'};
                $bkShelfMidRecId = $rec->{'rid'};
            }             
            $rec->{'callNum1St'} =~ s/ +/<br>/g; 
        }

        my $pRange = 10;
        my @rangedPageList = tmpl_rangedPageList($hits, $curPage, $pSize, $pRange);
        my $recTo =  $offset  + $pSize ;
        if($recTo > $hits) {
            $recTo = $hits;
        }
        $template->param(
            bkShelfMidCallno    =>$bkShelfMidCallno,
            bkShelfMidRecId     =>$bkShelfMidRecId,
            rs                  => $recList,
            rangedPageList      => \@rangedPageList,
            hits                => $hits,
            pNum                => $curPage,
            recFrom             => $offset +1,
            recTo               => $recTo ,
            "sortAttr_$sortAttr"=>1 , 
            showLocation        =>($showLocation eq '1')?1:0,
        );
         foreach my $var qw(facet generalInfo inclCircData studentILL){
            if(defined $rs->{$var}){
                $template->param($var=>$rs->{$var});
            }
        }
    }
    else{
        #if($rs->{'suggestion'} && $rs->{'suggestion'}->{'term'} ne ''){
                $template->param(
                        suggestion=>$rs->{'suggestion'}->{'term'}  ,
                        sugField  =>$rs->{'suggestion'}->{'field'}
                );
        #}
    }
                  


 
#Mon, Nov 30, 2009 @ 09:04:13 EST
#
my $stdMsgMap  =loc_getMsgFile('search/standard.msg',$msgValMap);
loc_write($template,$stdMsgMap);
if ($zid) {
    my $infoMsgMap = loc_getMsgFile('record/bib_info.msg');
    loc_write($template, $infoMsgMap);
}

my @siteTab = srch_zTab($dbh, $zid);
$template->param(
    zid => $zid,
    siteTab => \@siteTab,
);

tmpl_write($dbh, $cgi, \@cookieList, $template);
   
   
#=======================================================
sub setSearchFormFilter{

    my $formatMsgMap  =loc_getMsgFile('search/facet.msg',{});
    my $refineFilter=[];
    my @fieldArr =qw(language format author subject dewey era genre);
    foreach my $f(@fieldArr){
        if($input->{$f .'Filter'} ne ''){
            my $fTxt = $formatMsgMap->{$f};
            my $fVal=$input->{$f .'Filter'};
            $fVal= $formatMsgMap->{$fVal} if($f =~ m/language|format/gi);
            push @$refineFilter,{field=>$fTxt,value=>$fVal ,filter=>$f .'Filter'};
        }
    }
    $template->param(refineFilter => $refineFilter);
}
   
#=======================================================
sub setPageNavForm{
    my ($cgi,)=@_;
    my $input=$cgi->Vars();
    my @recType     = $cgi->param('recType');
    my $navFormInput=[];
    foreach my $iName(keys %$input){
        push @$navFormInput,{name=>$iName, value=>$input->{$iName}};
    }
    my @recType     = $cgi->param('recType');
    foreach my $rType(@recType){
        push @$navFormInput,{name=>'recType', value=>$rType};
    }
    my @fieldArr =qw(languageFilter formatFilter authorFilter subjectFilter deweyFilter eraFilter genreFilter);
    foreach my $f(@fieldArr){
        if(!defined $input->{$f}){
            push @$navFormInput,{name=>$f, value=>''};
        }
    }
    if(!defined $input->{'pNum'}){
        push @$navFormInput,{name=>'pNum', value=>1 };
    }
    $template->param(navFormInput => $navFormInput);
}
#=======================================================
sub search_localDb{
    my @recType     = $cgi->param('recType');
    my $filter;
    $filter->{'recType'}=\@recType;
    $rs =searchSolr($input,$filter);
    my $suggestion=undef;
    my $sfCount=0;

    if($rs->{'hits'}>0){
        mapFacetMsg($rs->{'facet'});  
        addToggleAnchor2FacetList($rs->{'facet'});
    }
    else{
        foreach my $cgiInput (keys %$input) {
            $sfCount++ if ($cgiInput =~ m/^sf[\d]+/);
        }
        if ($sfCount ==1 ) {
            my $fieldSrch = $input->{'sf0'};
            ($fieldSrch && $fieldSrch ne '')||($fieldSrch = 'title');

            my $s= slr_getSuggestion($fieldSrch ,$input->{'kw0'});
            if($s ne ""){
                $suggestion={field=>$fieldSrch,term=>$s};
            }
        }

    }
    return { hits=>$rs->{'hits'},
             recordList=>$rs->{'recordList'},
             suggestion=>$suggestion,
             facet=>$rs->{'facet'}
           };
}
#=======================================================
sub search_z3950{

    my ($hits,$recordList) =searchPQF($input,$cgi,$zid);
    my $retVal={ hits=>$hits,recordList=>$recordList};
    my $generalInfo=[];
    my $ridList = '';
    my $marcXmlParser=Opals::MarcXmlParser->new();
    foreach my $record (@$recordList) {
        $ridList .= $record->{'rid'} . ',';
        my $gi =$marcXmlParser->getRecInfoGeneral($record->{'xml'});
        $record->{'isbn'}=$gi->{'isbn'} if(defined $gi->{'isbn'});
        $gi->{'rid'} = $record->{'rid'};
        push @$generalInfo, $gi;
    }
    $ridList =~ s/[^,\d]//g;
    $ridList =~ s/(^,+|,+$)//g;
    $ridList =~ s/,+/,/g;
    my($circData,$inclCircData,$studentILL)=(undef,0,0);
    if ($ridList) {
        my $zdb = srch_zDatabase($dbh, $zid);
        $inclCircData=$zdb->{'circData'};
        my $uid = $template->param('curUserId');
        $studentILL = ($zdb->{'studentILL'} && $uid)?1:0;

        # 1. send request to union
        if ($zdb->{'circData'}) {
            $circData = wsc_getCircData($zdb->{'host'}, $ridList);
        }
        # 2. append results from union
        foreach my $rec (@{$recordList}) {
            my $rid = $rec->{'rid'};
            foreach my $sf852a (@{$rec->{'stat852a'}}) {
                my $sf852a_value = $sf852a->{'code852a'};
                foreach my $sf852b (@{$sf852a->{'list852b'}}) {
                    my $sf852b_value = $sf852b->{'code852b'};
                    my $location = $sf852b->{'location'};

                    foreach my $k (keys %{$circData->{$rid}->{$location}}) {
                        $sf852b->{$k} = 
                            $circData->{$rid}->{$location}->{$k};

                        if ($circData->{$rid}->{$location}->{'unionId'} eq 
                                $zdb->{'locationId'}) {
                            $sf852b->{'isLocal'} = 1;
                        }
                    }
                }
            }
        }
    }
    $retVal->{'generalInfo'}=$generalInfo; 
    $retVal->{'inclCircData'}=$inclCircData; 
    $retVal->{'studentILL'}=$studentILL; 
    return $retVal;
}
#=======================================================
sub getNewItemList{
    my ($dbh)=@_;
    my $newItemList="";
    my $pid =0;
    $pid =$dbh->selectrow_array("select pid from opl_portlet where type='newItemList'");
    if ($pid){$pid=35;

        my $prop = getPortletProp($dbh,$pid);
        my ($nItemShow,$fieldsShow , $showBookCover);
        foreach my $p(@$prop){
            $nItemShow       = $p->{'val'} if($p->{'var'} eq 'nItemShow');
            $fieldsShow      = $p->{'val'} if($p->{'var'} eq 'fieldsShow');
            $showBookCover   = $p->{'val'} if($p->{'var'} eq 'showBookCover');
        }
        $newItemList=portal_getNewItemList($dbh,$nItemShow,$fieldsShow,$showBookCover,'searchPage');

    my $self = $ENV{'SCRIPT_NAME'};#(caller(0))[1];
    }
    return ($pid,$newItemList);
}   
#=======================================================
sub getPortletProp{
  my($dbh,$pid)=@_;
    my $prop=[];
    
    my $sth = $dbh->prepare("select var,val from opl_portletProp where pid=?");
    $sth->execute($pid); 
    while( my ($var,$val) = $sth->fetchrow_array){
        push @$prop,{var=>$var,val=>$val};
    }
    $sth->finish;
    return $prop;

}

#=======================================================
sub searchSolr{
    my ($input,$filter) =@_;
    my $lQuery=slr_buildSearchQuery($input,$filter);
    my $rs=undef;
    if($lQuery ne ''){
        $rs = slr_search({lQuery=>$lQuery,recFormat=>'brief',
                             sortAttr=>$sortAttr,sortDir=>$sortOrder,
                             offset=>$offset,size=>$pSize,
                             incCircStatus=>1});  
    }
    return $rs;
}

#=======================================================
sub searchPQF{ 
    my($input,$cgi,$zid)=@_;
    my $pqf =srch_buildPQF($input,$cgi,$zid);
    my ($resultSize, $result)=(0,undef);
    if($pqf){
        ($resultSize, $result) = srch_searchRecord($dbh, $zid, 'b', $pqf, $offset, $pSize);
    }
    return ($resultSize, $result);
}

#=======================================================
sub getBookCover{
    my($recList)=@_;
    my  $awsId =Opals::Context->preference('amazonId');
    my  $awsSecretKey =Opals::Context->preference('amazonSecreteKey');
    my  $syndeticsId =Opals::Context->preference('syndeticsId');
    if($syndeticsId ne''){
        getBookCover_syndetics($recList);
    }
    elsif($awsId ne '' && $awsSecretKey ne ''){
        getBookCover_amazon($recList,$awsId,$awsSecretKey);
    }
    else{
        getBookCover_google($recList);
    }

}

#=======================================================
sub getBookCover_amazon{
    my($recList,$awsId,$awsSecretKey)=@_;
    my $isbnList="";
    my $isbnFixTbl={};
    foreach my $r(@$recList){
        foreach my $i(@{$r->{'isbn'}}){
            $isbnFixTbl->{$i->{'item'}}=_fixISBN($i->{'item'});
            $isbnList .= "," . $isbnFixTbl->{$i->{'item'}};
        }
    }
    if($isbnList ne ''){
        my $bookCoverUrls = bookCover_getUrl($isbnList, $awsId, $awsSecretKey);
        foreach my $rec(@$recList){
            foreach my $i(@{$rec->{'isbn'}}){
                my $isbnfixed=$isbnFixTbl->{$i->{'item'}};
                if($bookCoverUrls->{$isbnfixed}){
                    if($bookCoverUrls->{$isbnfixed}->{'small'}){
                        $rec->{'bookcoverURL'}=$bookCoverUrls->{$isbnfixed}->{'small'};
                    }
                    last;
                }
            }
        }
    }
}
#=======================================================
sub getBookCover_syndetics{
    my($recList)=@_;
    foreach my $rec(@$recList){
        my $isbnList="";
        foreach my $i(@{$rec->{'isbn'}}){
            $isbnList .= "," if($isbnList ne '');
            $isbnList .= $i->{'item'};
        }
        if($isbnList ne ''){
            #$rec->{'bookcoverURL'}=$template->{'url_bookcover'} . "?size=sc&isbn=$isbnList" ;
            $rec->{'bookcoverURL'}="/bin/search/bookcover?size=sc&isbn=$isbnList" ;
        }
    }
}
#=======================================================
sub getBookCover_google{
    my($recList)=@_;
    my $isbn="zzzz";
    foreach my $rec(@$recList){
        $isbn=$rec->{'isbn_first'} ne ''? _fixISBN($rec->{'isbn_first'}):"zzzz";        
        $rec->{'bookcoverURL'}="http://books.google.com/books?printsec=frontcover&frontcover&img=1&zoom=1&vid=ISBN$isbn" ;
        
    }
}

#////////////////////////////////////////////////////////////////////////////
sub _fixISBN{
    my($isbn)=@_;
    $isbn=~ m/([\D^x^X]*)([\dxX][\dxX -]{8,}[\dxX])([\D^x^X]*)/;
    $isbn= $2;
    $isbn=~ s/[- ]//g;
    return $isbn; 
}
#////////////////////////////////////////////////////////////////////////////
sub getRating{
    my ($recList)=@_;
    my  $rating =Opals::Context->preference('rating');
    if($rating && $rating ==2 ){
        foreach my $rec(@$recList){
            my $noReview  = cmntRating_numOfRating($dbh,$rec->{'rid'});
            my $avgRating = cmntRating_getAvgRating($dbh,$rec->{'rid'});
            my $numOfStars =floor($avgRating);
            my $fraction= $avgRating - $numOfStars ;
            if($fraction >0.25 && $fraction<0.75){
                $numOfStars += 0.5;
            }
            elsif($fraction >0.75){
                $numOfStars += 1;
            }

            my $avgRating = sprintf("%.2f", $avgRating);
            $rec->{'rateRec'} = $avgRating;
            $rec->{'numReview'} = $noReview;
            $rec->{'numOfStars'} = $numOfStars;
           }
    }
}
#=======================================================
sub mapFacetMsg{
    my ($facet)=@_;
    foreach my $fa(@$facet){
        $fa->{'fieldTxt'} =$formatMsgMap->{$fa->{'field'}};
        $fa->{'hasIcon'}=1 if($fa->{'field'} eq 'format');
        foreach my $item(@{$fa->{'facetList'}}){
            if($fa->{'field'} =~ m/format|language/){
               $item->{'facetTxt'}=$formatMsgMap->{$item->{'facet'}};
               if($item->{'facetTxt'} eq''){
                    $item->{'facetTxt'}="undefined" ;
                    $item->{'facet'}='undef';
               }
            }
            else{
                $item->{'facetTxt'}=$item->{'facet'};
            }
        }
    }
    
}
#=======================================================
sub addToggleAnchor2FacetList{
    my ($facet)=@_;
    my $facetToggleId=0;
    foreach my $fa(@$facet){
        if(scalar(@{$fa->{'facetList'}}>16) ){
            splice @{$fa->{'facetList'}}, 10, 0, {facet=>"",
                                                  toggleMore=>1,
                                                  facetToggleId=>$facetToggleId};
            push @{$fa->{'facetList'}},{facet=>"",
                                        toggleLess=>1,
                                        facetToggleId=>$facetToggleId};
            $facetToggleId++;
        }
    }

}
#=======================================================
# Fri, Oct 24, 2008 @ 09:16:19 EDT

sub writeSortParam2tmpl{
    my ($input) =@_;
    my $sortAttr  = $input->{'sortAttr'};
    my $sortOrder = $input->{'sortOrder'};
    if(!$sortAttr &&  $input->{'sf0'} eq '5006'){
        $sortAttr=4;
    }
    if(! defined $sortOrder ){ $sortOrder =0;}
   $template->param(
    sortOrder           => $sortOrder,
    sortAttr            => $sortAttr,
    sortCallNum1st      => ($sortAttr == 5001)              ? 1 : 0,
    sort852c            => ($sortAttr == 8008)              ? 1 : 0,
    sortTitle           => ($sortAttr == 4)                 ? 1 : 0,
    sortAuthor          => ($sortAttr == 1003)              ? 1 : 0,
    sortPubDateSort     => ($sortAttr == 31)                ? 1 : 0,
    sortOrderReverse    => ($sortOrder && $sortOrder == 1)  ? 2 : 1,
    sortDown            => ($sortOrder && $sortOrder == 1)  ? 1 : 0,
    );



}
