#!/usr/bin/perl

#use utf8;
use strict;
use JSON;
use CGI;

use Opals::Session qw(
    SessionHdl_getSSID
);
use Opals::MarcXmlParser;

use Opals::Context;
use Opals::Constant;
use JSON;
use POSIX qw(
    ceil
);
use Opals::BookCover qw(
  bookCover_google
  bookCover_syndetics

);
use Opals::Circulation qw(
  circ_numItemsAvailable
);

my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }
my $request=getRequest();

#$request:op,record,pfId
#
my $cgi    = CGI->new;
my $FN_MAP={
    add                 =>\&_saveClsft,
    getClsf             =>\&_getClsft,
    getClsfList         =>\&_getClsftList,
    update              =>\&_saveClsft,
    delete              =>\&_delClsftItem,
    getClsfItemList     =>\&_getClsftItem,
    getClsfItemCount     =>\&_getClsftItemCount,
    getClsfItemCount4edit =>\&_getClsftItemCount4edit,
    getClsfItemList4edit  =>\&_getClsftItem_edit
    
    };

my $SORT_MAP={
    title =>"titleSort,author,callNumber",
    author =>"author,titleSort,callNumber",
    callNumber =>"callNumber,author,titleSort",
    pubDate =>"pubDateSort desc,author,title",
};
#------------------------------

my $rs={};
my $action=$request->{'op'};
if(defined $FN_MAP->{$action}){
    my $fn=$FN_MAP->{$action};
    $rs= &$fn($dbh,$request);
}
print "Content-type: text/plain\n\n";
print   to_json($rs,{pretty=>1});
#-------------------------------------------------------------------------------
sub _delClsftItem{
    my($dbh,$rq)=@_;
    $dbh->do("delete from opl_classif where cid=?",undef,$rq->{'cid'});
    $dbh->do("delete from opl_classifItem where cid=?",undef,$rq->{'cid'});
    return {deleted=>$rq->{'cid'}};
}
#-------------------------------------------------------------------------------
sub _getClsftItemCount{
    my($dbh,$rq)=@_;
    my $sql =(<<_SQL_);
    select count(distinct i.rid) totalItem
    from opl_classifItem c inner join opl_item i using(rid) 
    where i.barcode not regexp '___' && cid=?
_SQL_

    my $rs=$dbh->selectrow_hashref($sql,undef,$rq->{'cid'});
    return $rs;
}
#-------------------------------------------------------------------------------
sub _getClsftItemCount4edit{
    my($dbh,$rq)=@_;
    return {totalItem=>0} if(!defined $rq->{'cid'});
    my $cid=$rq->{'cid'};
    my $sql=<<_SQL_;
    select count(distinct i.rid) totalItem 
    from (select rid from opl_sessionVar 
          where var ='classifEdit' && note regexp ':$cid' 
          union select c.rid 
            from opl_classifItem c 
            where c.cid=$cid) t 
          inner join opl_item i on i.rid=t.rid && i.barcode not regexp '___'  
_SQL_
    my $rs=$dbh->selectrow_hashref($sql);
    return $rs;
}
 #-------------------------------------------------------------------------------
sub _getClsft{
    my($dbh,$rq)=@_;
    my $clsftn=$dbh->selectrow_hashref("select * from opl_classif where cid=?",undef,$rq->{'cid'});
    if($clsftn){
        ($clsftn->{'totalItem'})=$dbh->selectrow_array("select count(distinct i.rid) from opl_classifItem c inner join opl_item i using(rid) where i.barcode not regexp '___' &&  cid=?",undef,$rq->{'cid'});
    }
    else{
        $clsftn={};
    }
    return $clsftn;
}
#-------------------------------------------------------------------------------
sub _getClsftList{
    my($dbh,$rq)=@_;
    my $sth =$dbh->prepare("select * from opl_classif  where type=?");
    my $clsftList=[];
    my $type=$rq->{'type'}||1;
    $sth->execute($type);
    while(my $clsftn=$sth->fetchrow_hashref){
        ($clsftn->{'totalItem'})=$dbh->selectrow_array("select count(distinct i.rid) from opl_classifItem c inner join opl_item i using(rid) where i.barcode not regexp '___' &&  cid=?",undef,$clsftn->{'cid'});
        push @$clsftList,$clsftn;
    }
    return $clsftList;
}

#------------------------------------------------------------------------------
sub _saveClsft{
    my($dbh,$rq)=@_;
        #added/deleted classification items are temporary stored in session table, 
        #save and delete function will retreive them from the opl_sessionVar table 
    my $clsftn=$rq->{'data'};
    my $ssid= SessionHdl_getSSID($cgi);
    my $cid = $clsftn->{'cid'};
    my $sth=$dbh->prepare("update opl_classif  set type=? ,className=?,description=? ,iconURL=?");
    if(defined$cid && $cid>0){
        $dbh->do("update opl_classif  set type=? ,className=? , description=? ,iconURL=? where cid=?",undef,
                  $clsftn->{'type'},$clsftn->{'className'},$clsftn->{'description'},$clsftn->{'iconURL'},$clsftn->{'cid'});

        $dbh->do("delete i.* from opl_classifItem i inner join opl_sessionVar s on s.rid=i.rid && s.note='del:$cid' 
             where ssid=? && var='classifEdit'",undef,$ssid);
        $dbh->do("replace into opl_classifItem(cid,rid) select $cid,rid from opl_sessionVar s  
             where ssid=? && var='classifEdit' && note='add:$cid'",undef,$ssid);
        $dbh->do("delete from opl_sessionVar where ssid=? && var='classifEdit' && note regexp ':$cid'",undef,$ssid);
    }
    else{
        $dbh->do("insert into opl_classif  set type=? ,className=?, description=? ,iconURL=?, createdDate=now()",undef,
                 $clsftn->{'type'},$clsftn->{'className'},$clsftn->{'description'},$clsftn->{'iconURL'});
        $cid =$dbh->{'mysql_insertid'}; 
        $clsftn->{'cid'}=$cid;       
        $dbh->do("insert into opl_classifItem(cid,rid) select $cid ,rid from opl_sessionVar s  
             where ssid=? && var='classifEdit' && note='add:0'",undef,$ssid);
        $dbh->do("delete from opl_sessionVar where ssid=? && var='classifEdit' && note regexp ':0'",undef,$ssid);
    }
    my $o=_getClsftItemCount($dbh,$clsftn);
    $clsftn->{'totalItem'}=$o->{'totalItem'};
    return $clsftn;
   
}

#-------------------------------------------------------------------------------
sub _delClsft{
    my($dbh,$cid)=@_;
    $dbh->do("delete from opl_classif where cid=?", undef,$cid);
    $dbh->do("delete from opl_classifItem where cid=?", undef,$cid);
}

#-------------------------------------------------------------------------------
sub _getClsftItem{
    my($dbh,$rq)=@_;

    my $ssid= SessionHdl_getSSID($cgi);
    my $cid=$rq->{'cid'};
    my $offset=$rq->{'offset'};
    my $size=$rq->{'size'};
    $offset=0  if(!$offset || $offset !~ m/\d+/);
    $size  =10 if(!$size || $size !~ m/\d+/);
    my $ridList=[];
    my $sortCond=$SORT_MAP->{"title"};
    if($rq->{'sortBy'} && defined $SORT_MAP->{$rq->{'sortBy'}}){
        $sortCond=$SORT_MAP->{$rq->{'sortBy'}};
    }
    my $rs=$dbh->selectrow_hashref("select className ,description,iconURL from opl_classif where cid=?",undef,$cid);
    $rs->{'totalItem'}=_getClsftItemCount($dbh,$rq)->{'totalItem'};
    my $sth=$dbh->prepare(<<_SQL_);
    select distinct c.rid
    from opl_classifItem c inner join opl_marcRecord m using(rid) 
         inner  join opl_item i on i.rid=m.rid && i.barcode not regexp '___'  
    where cid=?     
    order by $sortCond 
    limit $offset,$size
_SQL_

   $sth->execute($cid);
   while(my ($rid)=$sth->fetchrow_array){
       push @$ridList,{rid=>$rid,deleted=>0};
   }
   $rs->{'itemList'}=  getRecInfo($dbh,$ridList);
   return $rs;
}

#-------------------------------------------------------------------------------
sub _getClsftItem_edit{
    my($dbh,$rq)=@_;
    my $ssid= SessionHdl_getSSID($cgi);
    my $cid=$rq->{'cid'};
    my $offset=$rq->{'offset'};
    my $size=$rq->{'size'};
    $offset=0  if(!$offset || $offset !~ m/\d+/);
    $size  =10 if(!$size || $size !~ m/\d+/);

    my $sortCond=$SORT_MAP->{"title"};
    if($rq->{'sortBy'} && defined $SORT_MAP->{$rq->{'sortBy'}}){
        $sortCond=$SORT_MAP->{$rq->{'sortBy'}};
    }
    my $rs=$dbh->selectrow_hashref("select className ,description from opl_classif where cid=?",undef,$cid);
    $rs->{'totalItem'}=_getClsftItemCount4edit($dbh,$rq)->{'totalItem'};

    #($rs->{'title'})=$dbh->selectrow_array("select className from opl_classif where cid=?",undef,$cid);
    if($rs->{'totalItem'}>0){
        my $ridList=[];
        my $sth=$dbh->prepare(<<_SQL_);
        select distinct m.rid 
        from (select rid from opl_sessionVar 
                where ssid='$ssid' && var ='classifEdit' && note='add:$cid' 
              union select rid 
                from opl_classifItem where cid=$cid) t 
              inner join opl_marcRecord m using(rid) 
              inner join opl_item i on i.rid=m.rid && i.barcode not regexp '___'  
        order by $sortCond
        limit $offset,$size
_SQL_

       $sth->execute();
       while(my ($rid)=$sth->fetchrow_array){
           my ($deleted)=$dbh->selectrow_array("select count(*) from opl_sessionVar where  ssid='$ssid' &&  var='classifEdit' && note='del:$cid' && rid=$rid");
           push @$ridList,{rid=>$rid,deleted=>$deleted};
       }
       $rs->{'itemList'}=  getRecInfo($dbh,$ridList);
    }
   return $rs;

}
  
#-------------------------------------------------------------------------------
sub getRequest{
  my $fineList=[];
  my $request={};
  if ($ENV{'REQUEST_METHOD'} eq "POST") {
        my $json ="";
        while (<STDIN>) {
            $json .= $_;
        }
        $request = decode_json($json);
   }
   return $request;
}
#------------------------------------------------------------------------------
sub recordPath {
    my ($rid) = @_;
    
    my $zRoot   = Opals::Context->config('zRoot');
    my $zPort   = Opals::Context->config('zPort');
    my $zDatabase = Opals::Context->config('zDatabase');
    my $dir     = "$zRoot/$zPort/record/$zDatabase/" . ceil($rid/1000);

    return $dir;
}
#=======================================================
sub getBookCover {
  my ($recList)    = @_;
  my $awsSecretKey = Opals::Context->preference('amazonSecreteKey');
  my $syndeticsId  = Opals::Context->preference('syndeticsId');
  if ($syndeticsId ne '') {
    bookCover_syndetics($recList);
  }
  else {
    bookCover_google($recList, "m");
  }

}
#=======================================================
sub  getRecInfo{
  my ($dbh,$ridList)= @_;
  my $rs=[];
  my $indexConfFile  = Opals::Context->config('sIndexConfig');
  my $marcXmlParser=Opals::MarcXmlParser->new($indexConfFile);
  foreach my $r (@$ridList){
      my $rid=$r->{'rid'};
       my $fname=recordPath($rid)."/$rid.xml";

       my $rec=$marcXmlParser->getRecInfoGeneral_file($fname);
       if($rec){
           $rec->{'rid'}=$rid;
           $rec->{'deleted'}=$r->{'deleted'};
           $rec->{'numOfCopyAvbl'}=circ_numItemsAvailable($dbh,$rid);
           push @$rs,$rec;
       }
   }
  getBookCover($rs);
  return $rs;
}

