#!/usr/bin/perl

#use utf8;
use strict;
use JSON;
use CGI;
use Digest::SHA qw(
    sha1_base64
    sha1_hex
);
use POSIX qw(
    ceil
);
use Opals::Context;

use Opals::SolrIndex qw(
    slr_search
    slr_buildSearchQuery
    srl_buildQuery_datafield
);

use Opals::Report qw(
    rpt_getItemListByStatus
    rpt_getItemListByStatus_current
);
use Opals::Eq_SolrSearch;
use Opals::Equipment qw(
    
    eq_item_findByRId

);

use Opals::Tb_Search qw(

    search_rpt_getItemListByStatus

);


use Opals::Session qw(
    SessionHdl_viewMovingHolding
    SessionHdl_mhPrevNextRecord
    SessionHdl_moveHolding
    SessionHdl_setTarget
    SessionHdl_add
    SessionHdl_del
    SessionHdl_get
    SessionHdl_clearVar
    SessionHdl_exist_rid
    SessionHdl_exist_bc
    SessionHdl_count
    SessionHdl_getBriefRecList
    SessionHdl_getBrRecListByHolding
    SessionHdl_getSSID
    SessionHdl_rename
);
my $FN_MAP={
    rename=>\&renameVar,
    add=>\&add,
    del=>\&del,
    get=>\&get,
    clear=>\&clear,
    addAll=>{itemStatusRpt    =>\&addAll_itemStatusList,
             searchRs         =>\&addAll_searchRs,
             eq_searchRs      =>\&addAll_eq_searchRs,
             tb_itemStatusRpt =>\&addAll_tbItemStatusList,
             ge               =>\&addAll_ge,
             modifiedRec      =>\&addAll_modifiedRec
            },
    count=>\&count
};
my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }
my $request=getRequest();
my $cgi    = CGI->new;
my $ssid   = SessionHdl_getSSID($cgi);
my $ssidCookie=CGI::Cookie->new(-name=>'globalSessionID',-value=>$ssid);

my $action=$request->{'action'};
my $selectSrc=$request->{'selectSrc'};
my $count;
my $selItems;
if(defined $FN_MAP->{$action}){
    my $fn=undef;
    if($action eq 'addAll' && defined $FN_MAP->{$action}->{$selectSrc}){
        $fn =$FN_MAP->{$action}->{$selectSrc};
    }
    else{
        $fn = $FN_MAP->{$action};
    }

    if(defined $fn){
        if( $action ne 'count'){
            if($action eq 'get'){
                print debbug "111\n";
                $selItems=&$fn();
            }
            else{
                &$fn();
            }
        }
        $count=count();
    }
}
print "Set-Cookie: $ssidCookie\n";
print "Content-type: text/plain\n\n";

my $rs={status=>1,rs=>$count,selItems=>$selItems};
print   to_json($rs);

#-------------------------------------------------------------------------------
sub renameVar{
    SessionHdl_rename($dbh,$ssid,$request->{'varName_old'},$request->{'varName_new'});
}

#-------------------------------------------------------------------------------
sub add{
   foreach my $item(@{$request->{'itemList'}}){
       #if(!SessionHdl_exist_bc($dbh,$ssid, $request->{'varName'},$item->{'barcode'})){
            SessionHdl_add($dbh,$ssid, $request->{'varName'},$item->{'rid'},$item->{'barcode'},$item->{'note'});
       #}
   }
}
#-------------------------------------------------------------------------------
sub del{
   foreach my $item(@{$request->{'itemList'}}){
        SessionHdl_del($dbh,$ssid,$request->{'varName'},$item->{'rid'},$item->{'barcode'},$item->{'note'});
   }
   return 1;
   
}
#-------------------------------------------------------------------------------
sub get{
    return SessionHdl_get($dbh,$ssid,$request->{'varName'},$request->{'offset'},$request->{'count'});
}
#-------------------------------------------------------------------------------
sub count{
    my ($ridCount,$bcCount)= SessionHdl_count($dbh,$ssid,$request->{'varName'});
    return {ridCount=>$ridCount,bcCount=>$bcCount};
}
#-------------------------------------------------------------------------------
sub clear{
   SessionHdl_clearVar($dbh,$ssid,$request->{'varName'});
   return 1;
}

#------------------------------------------------------------------------------
sub addAll_modifiedRec{
    my $dateFrom =$request->{'from'};
    my $dateTo   =$request->{'to'} ;
    my $sort    =$request->{'sort'};
    my $sortDir =$request->{'sortDir'};
    
    my $pNum    =$request->{'pNum'} ;
    my $pagesize=$request->{'pagesize'} ;

    my $pageoffset = $pNum;
    if ( !$pageoffset ) {
        $pageoffset = 0;
    }
    else {
        $pageoffset = ($pNum - 1) * $pagesize;
    }
  
   my ($countRecord)= $dbh->selectrow_array("select  count(distinct m.rid)
from    opl_marcRecord m  inner join opl_item i on i.rid=m.rid
where  i.available=1 &&  m.modDate between '$dateFrom' and  '$dateTo' + interval 1 day 
        && m.modDate <> i.dateImport");
       
    my $sql = <<_STH_;
select  distinct m.rid,m.title,m.author,m.modDate,i.callNumber
from    opl_marcRecord m  inner join opl_item i on i.rid=m.rid
where  i.available=1 &&  m.modDate between '$dateFrom' and  '$dateTo' + interval 1 day 
        && m.modDate <> i.dateImport
        && i.barcode not regexp '___'
group by m.rid        
_STH_
    
    
    
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    

    my $pNum = -1;
    my @recordList =();
    my $holdingList;
    my $preRid=0;
    my $barcode;
    my $holdingList;
    while (my $r = $sth->fetchrow_hashref) {
        if($preRid != $r->{'rid'}){
            my $rec;
            $preRid = $r->{'rid'};
            $rec->{'rid'}= $r->{'rid'};
            $rec->{'title'}= $r->{'title'};
            $rec->{'author'}= $r->{'author'};
            $rec->{'modDate'}= $r->{'modDate'};
            $rec->{'callNumber'}= $r->{'callNumber'};
            $pNum++;        
            $rec->{'odd'} = $pNum%2;
            $rec->{'order'} = $pNum;
            $rec->{'marcXmlExist'}=isMarcXmlExist($rec->{'rid'});
            $rec->{'holdings'} =getRecordHolding($dbh, $rec->{'rid'});
            push @recordList, $rec;
        }
        
        if($r->{'barcode'} =~m/^\_\_\_(.*)\_[\d]+$/){
            $barcode=$1;
        }
        else{
           $barcode='n/a';
        }
     }
    $sth->finish;
   # if($countRecord>0){
   #     foreach my $item(@recordList){
   #         SessionHdl_add($dbh,$ssid,$request->{'varName'},$item->{'rid'},'');
   #     }
   # }
       
}
#------------------------------------------------------------------------------
sub isMarcXmlExist{
    my ($rid) =@_;
    my $zRoot   = Opals::Context->config('zRoot');
    my $zDatabase = Opals::Context->config('zDatabase');
    my $dir     = "$zRoot/$zDatabase/" . ceil($rid/1000);
    
     
    return (-f "$dir/$rid.xml");

}#------------------------------------------------------------------------------
sub getRecordHolding{
    my ($dbh,$rid) =@_;
    my $sql = <<_STH_;
select  barcode
from    opl_item 
where   available=1 && rid=? 
        && barcode not regexp '___'
_STH_
  my $sth = $dbh->prepare($sql);
    $sth->execute($rid);
    my $holdingList;
    while (my $i = $sth->fetchrow_hashref) {
        SessionHdl_add($dbh,$ssid,$request->{'varName'},$rid,$i->{'barcode'});
        push @$holdingList, $i;
    }
    return $holdingList;
}

#-------------------------------------------------------------------------------

sub addAll_itemStatusList{ 

    my $from      =$request->{'from'};
    my $to        =$request->{'to'} ;
    my $status    =$request->{'status'};
    my $sort      =$request->{'sort'};
    my $sortDir   =$request->{'sortDir'};
    my $incIll    =$request->{'incIll'};
    my $incTmp    =$request->{'incTmp'};
    my $filter    =$request->{'filter'}|| undef;
    my $varName   =$request->{'varName'};
    my $rptType   =$request->{'rptType'} || 'stat'; #current or statistical

 my $rs={};
    if($rptType eq 'current'){
        $rs = rpt_getItemListByStatus_current($dbh,$status,undef,undef,$sort,$sortDir,$incIll,$incTmp,undef,undef,$filter);
    }
    else{
        $rs = rpt_getItemListByStatus($dbh,$status,$from,$to,undef,undef,$sort,$sortDir,$incIll,$incTmp,undef,undef,$filter);
    }
   
    if($rs->{'found'}>0){
        foreach my $item(@{$rs->{'itemList'}}){
            SessionHdl_add($dbh,$ssid,$varName,$item->{'rid'},$item->{'barcode'},$item->{'ondate'});

        }
    }

}
#-------------------------------------------------------------------------------
sub addAll_searchRs{
    my $filter;
    if(defined $request->{'searchParam'}->{'recType'} 
        && ref($request->{'searchParam'}->{'recType'}) eq "ARRAY" 
        && scalar(@{$request->{'searchParam'}->{'recType'}})>0){
        $filter->{'recType'}= $request->{'searchParam'}->{'recType'};
    }

    my $lQuery=slr_buildSearchQuery($request->{'searchParam'},$filter);
    return _addAll_searchRs($lQuery);
}
#-------------------------------------------------------------------------------
sub addAll_ge{
    my $filter;
    my $from =$request->{'searchParam'}->{'dateImportFrom'};
    my $to   =$request->{'searchParam'}->{'dateImportTo'}; 
    if((defined $from && $from ne '' ) || (defined $to && $to ne '' ) ){
        $filter->{'dateImport'}={from=>$from,to=>$to};
    }
    if(defined $request->{'searchParam'}->{'recType'} && $request->{'searchParam'}->{'recType'} ne ''){
        $filter->{'recType'}=[$request->{'searchParam'}->{'recType'}];
    }
    my $lQuery=srl_buildQuery_datafield($request->{'searchParam'}->{'srchFields'},$filter);
    return _addAll_searchRs($lQuery);
}


#-------------------------------------------------------------------------------
sub _addAll_searchRs{
    my($lQuery) =@_;
    my $varName= $request->{'varName'};
    my $note= $request->{'note'}||"";
    my $rs=undef;
    my ($offset,$size)=(0,100);
    if($lQuery ne ''){
        while(1){        
            $rs = slr_search({lQuery=>$lQuery,recFormat=>'detail',
                             offset=>$offset,size=>$size});  
           if($rs->{"hits"}>0){
               foreach my $rec (@{$rs->{'recordList'}}){
                   foreach my $h(@{$rec->{'itemList'}}){
                        SessionHdl_add($dbh,$ssid,$varName,$rec->{'rid'},$h->{'barcode'},$note);
                   }
               }
               $offset +=$size;
               last if($offset>$rs->{"hits"});
           }
           else{ last;}
        
        }
        if($request->{'filterLoan'} ==1){
            $dbh->do("delete s from opl_sessionVar s inner join opl_loan l on l.barcode=s.barcode where l.dateReturn is null && s.var=? && s.ssid=?",undef,$varName,$ssid);
        }
    }
    return $rs;
}

#-------------------------------------------------------------------------------
sub addAll_tbItemStatusList{ 

    my $from    =$request->{'from'};
    my $to      =$request->{'to'} ;
    my $status  =$request->{'status'};
    my $sort    =$request->{'sort'};
    my $sortDir =$request->{'sortDir'};
    my $varName= $request->{'varName'};
    my $rs = search_rpt_getItemListByStatus ($dbh, 0, 10000,  $from,  $to, $sort ,$sortDir,$status);
    #my $rs =rpt_getItemListByStatus($dbh,$status,$from,$to,undef,undef,$sort,$sortDir,$incIllTmp);
    if($rs->{'found'}>0){
        foreach my $item(@{$rs->{'itemList'}}){
            SessionHdl_add($dbh,$ssid,$varName,$item->{'rid'},$item->{'barcode'},$item->{'ondate'});
        }
    }
}


sub addAll_eq_searchRs{
   my $eq_solr = Opals::Eq_SolrSearch->new(dbh=>$dbh);
   my ($offset,$size)=(0,10);
   my $varName = $request->{'varName'};
   my $rs=undef;
   my $lQuery = $eq_solr->eq_slr_buildSearchQuery($request->{'searchParam'});
   $lQuery .= "&fl=rid,eq_name,barcode";
   if($lQuery ne ''){
     while(1) {
        $request->{'searchParam'}->{'offset'} = $offset;
        $request->{'searchParam'}->{'pSize'} = $size;
        $lQuery = $eq_solr->eq_slr_buildSearchQuery($request->{'searchParam'});
        my $params={
            lQuery=>$lQuery,
            displayStyle=>$request->{'searchParam'}->{'displayStyle'},
        };
        $rs = $eq_solr->eq_slr_search($params);
        if ($rs->{'hits'}>0){
          foreach my $r (@{$rs->{'recordList'}}){
            if ($request->{'searchParam'}->{'displayStyle'} eq "record") {
                $r->{'itemList'} = eq_item_findByRId($dbh,$r->{'rid'});
                foreach my $h(@{$r->{'itemList'}}){
                    SessionHdl_add($dbh,$ssid, $varName,$r->{'rid'},$h->{'barcode'});
                }
            }else{
                SessionHdl_add($dbh,$ssid, $varName,$r->{'rid'},$r->{'barcode'})
            }
          }
          $offset +=$size;
          last if($offset>$rs->{"hits"});
        }
        else{last;}
     }
     if($request->{'filterLoan'} ==1){
        $dbh->do("delete s from opl_sessionVar s inner join eq_loan l on l.barcode=s.barcode where l.dateReturn is null && s.var=? && s.ssid=?",undef,$varName,$ssid);
        }
   } 
   return $rs;
}


#-------------------------------------------------------------------------------
sub getRequest{
  my $in={};
  if ($ENV{'REQUEST_METHOD'} eq "POST") {
        my $json ="";
        while (<STDIN>) {
            $json .= $_;
        }
        $in = decode_json($json);
   }
   return $in;
}
#------------------------------------------------------------------------------
