#!/usr/bin/perl
package SearchEqFn;
#use utf8;
use strict;
use Opals::REST;
use Opals::Context;
our @ISA =qw(Opals::REST);


use Time::localtime;

use Opals::Constant;
use Opals::Eq_SolrSearch;
use Opals::Session qw(
    SessionHdl_getSSID
);
my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }
my $SEARCH_FUNCTION_MAP={
     search             =>\&search,
     searchByNoCopy     =>\&searchByNoCopy
};
#use Opals::Eq_Record qw(
use Opals::Equipment qw(
   eq_record_getInfo
   eq_building_getList
);

use Opals::Eq_Circulation qw(
    eq_circ_getItemStatus
    eq_circ_infoRecord
);
use JSON;

my $searchEqFn= SearchEqFn->new($dbh,$SEARCH_FUNCTION_MAP);
#my $loginUser = $searchFn->{'authInfo'}->{'user'};
my $status_map = {
    1=>'Available',
    2=>'Reserved',
    3=>'On loan',
    4=>'Overdue',
    5=>'On hold',
    6=>'Unavailable',
    7=>'Lost',
    8=>'Damaged',
    9=>'Unknown',
    10=>'Restricted',
    11=>'Missing',
    12=>'On hold Expired',
    13=>'On Order',
    14=>'In Process',
    15=>'In Repair',
    16=>'Claim Return',
    17=>'Claim Never Return',
    18=>'Weed',
    19=>'Quarantine'
  };
my $cgi = $searchEqFn->{'cgi'};

$searchEqFn->processRequest();
#-------------------------------------------------------------------------------------------
sub search{
    my ($dbh,$param)=@_; 
    my $eq_solr = Opals::Eq_SolrSearch->new(dbh=>$dbh);
    open debug, ">/tmp/K";
    print debug "\n\nparams:", to_json($param,{pretty=>1}), "\n";
    my $lQuery = $eq_solr->eq_slr_srchQuery($param); 
    print debug "lQuery:$lQuery \n";
    $param->{'lQuery'}=$lQuery;
    my $rs = $eq_solr->eq_slr_search($param); #
    print debug "rs:",to_json($rs,{pretty=>1}),"\n";

    my $ssID = $cgi->cookie('globalSessionID');;
    print debug "ssid:$ssID \t $param->{'ssVarName'} \n";
    my $ssList = _getSessionHitList($dbh,$ssID,$param->{'ssVarName'});
    print debug "ssList: ", to_json($ssList) ,"\n";
    my $recRsPos = ($param->{'pNo'} - 1) * $param->{'pSize'};
    my (@rsAvail,@rsOnloan,@rsMissing) = ((),(),());
    my ($nAvail,$nOnloan,$nMissing) = (0,0,0);
    my $rid=0;
    foreach my $rec(@{$rs->{'recordList'}}){
      my $r;
      $rid = $rec->{'rid'}|| $rec->{'eq_rid'};
      print debug "rid:: $rid \n";
      if ($param->{'groupBy'} eq "record"){
        $rec->{'selected'}=$ssList && $ssList->{$rid}?1:0;
        $r = eq_record_getInfo($dbh,{'rid'=>$rid,'groupBy'=>$param->{'groupBy'}});
      }else{
        $rec->{'selected'}=$ssList && $ssList->{$rec->{'eq_barcode'}}?1:0;
        $r = eq_record_getInfo($dbh,{'rid'=>$rid,'barcode'=>$rec->{'eq_barcode'},'groupBy'=>$param->{'groupBy'}});
      }
      print debug "r :", to_json($r,{pretty=>1}),"\n";
      $rec->{'recRsPos'} = $recRsPos++; 
      $rec->{'record'} = $r->{'record'};
      $rec->{'item'} = $r->{'item'};
      $rec->{'items'} = $r->{'items'};
      if ($param->{'groupBy'} eq "barcode" || $param->{'groupBy'} eq "eq_barcode" ){
        $rec->{'circInfo'}=eq_circ_getItemStatus($dbh,{'barcode'=>$rec->{'eq_barcode'}||$rec->{'barcode'}});
      }
      else{
        #my $recCircInfo=eq_circ_infoRecord($dbh,$rid);
        #$rec->{'circInfo'}=$recCircInfo->{'circInfo'};
        $rec->{'circInfo'}=eq_circ_infoRecord($dbh,$rid);
      }
      $rec->{'status'}=$rec->{'circInfo'}->{'status'};
      $rec->{'statusTxt'}=$status_map->{$rec->{'circInfo'}->{'status'}} || "N/A";
    }
    foreach my $rec(@{$rs->{'recordList'}}){
      if ($param->{'circStatus'} eq 'available' && $rec && $rec->{'status'} == 1){
        push @rsAvail,$rec;
        $nAvail++;
      }
      elsif($param->{'circStatus'} eq 'onloan' && $rec->{'status'}==3){
        push @rsOnloan,$rec;
        $nOnloan++;
      }
      elsif($param->{'circStatus'} eq 'missing' && $rec->{'status'}==11){
        push @rsMissing,$rec;
        $nMissing++;
      }
    }
    if ($param->{'circStatus'} eq 'available'){
        $rs->{'recordList'} = \@rsAvail;
        $rs->{'hits'}=$nAvail;
    }
    elsif($param->{'circStatus'} eq 'onloan'){
        $rs->{'recordList'} = \@rsOnloan;
        $rs->{'hits'}=$nOnloan;
    }
    elsif($param->{'circStatus'} eq 'missing'){
        $rs->{'recordList'} = \@rsMissing;
        $rs->{'hits'}=$nMissing;
    }
    _formatRecord($dbh,$rs);
    print debug "\nrs 2:", to_json($rs,{pretty=>1}), "\n";
    close debug;
    return  $rs;
}

sub _formatRecord {
  my ($dbh,$rs)=@_; 
  my $showOnSearchFieldList = getShowOnSearchFieldList($dbh);
  my $buildingList =eq_building_getList($dbh);
  my $building={};
  foreach my $bld (@{$buildingList}) {
    $bld->{'selected'} = 0;
    #if ($bld->{'id'} eq $buildingSel){
    #    $bld->{'selected'} = 1;
    #}
    $building->{$bld->{'id'}} = $bld->{'name'};
  }

   print debug "showOnSearchFieldList", to_json($showOnSearchFieldList,{pretty=>1}),"\n";
   foreach my $r (@{$rs->{'recordList'}}) {
    $r->{'eq_name'} = ($r->{'eq_name'} =~ /^ *$/)?$r->{'rid'}:$r->{'eq_name'};
    $r->{'fieldList'} = [];
    my $bName="";
    foreach my $f (@{$showOnSearchFieldList}){
        if ($f->{'id'} eq '18'){
            $bName = ($building->{$r->{$f->{'id'}}})?$building->{$r->{$f->{'id'}}}:"";
        }
        push @{$r->{'fieldList'}},{
            id      => ($f->{'id'} eq '18')?"Building Name": $f->{'name'},
            value   => ($f->{'id'} eq '18' && $bName ne "")? $r->{$f->{'id'}} . "-" . $bName :$r->{$f->{'id'}} 
        }
    }
    #if ($displayStyle eq "linear"){
    #  $r->{'itemStatusInfo'} = circ_getItemStatus($dbh,{barcode=>$r->{'eq_barcode'}});
    #}
  }
  return $rs;
}


sub getShowOnSearchFieldList {
    my ($dbh) = @_;
    my $sth = $dbh->prepare("select id,name, showOnSearch from eq_def where showOnSearch=1");
    my @list;
    $sth->execute();
    while (my $f = $sth->fetchrow_hashref()) {
        push @list, $f;
    }
    return \@list;
}

#------------------------------------------------------------------------------------------- 
sub searchByNoCopy {
  my ($dbh,$p)=@_; 
	return undef if ( (!$p->{'noCopy'} && $p->{'noCopy'}!=0) || $p->{'noCopy'}<0);
  my ($resultSize, $recordList) = _eq_search_byNoCopy($dbh,$p);
  return {hits=>$resultSize,resultList=>$recordList}; 
}

sub _getSessionHitList{
    my ($dbh,$ssid,$vaName)=@_;
    my $itemList=[];
    my $hitList = {};
    my ($ridCount,$bcCount)=(0,0);
    my $sql ="select rid, barcode ";
    $sql .= "  from opl_sessionVar s ";
    $sql .= " where ssid= ? && var=? order by sOrder";
    my $sth =$dbh->prepare($sql);
    $sth->execute($ssid,$vaName);
    while( my $item=$sth->fetchrow_hashref){
        if($item->{'barcode'}){
          $hitList->{$item->{'barcode'}}=1;
        }
        if($item->{'rid'}){
          $hitList->{$item->{'rid'}}=1;
        }
    }
    return $hitList;
}
sub _eq_search_byNoCopy {
  my ($dbh,$p) = @_;
  my $sqlCount = "select count(*) from (select count(i.barcode) as count from eq_records r inner join eq_items i using(rid)  where r.deleted<>'1' && i.deleted<> '1'  group by r.rid having count>$p->{'noCopy'}) as c";

  my $sql = "select r.rid,r.rname as title,model.fValue as model, manu.fValue as manufacturer,count(i.barcode) as count  
  from eq_records r inner join eq_items i using(rid)  
    left outer join eq_recordFields model on model.rid=r.rid and model.fId=1 
    left outer join eq_recordFields manu on manu.rid=r.rid and manu.fId=3 
  where r.deleted <> '1'  && i.deleted<>'1'  
  group by i.rid having count > $p->{'noCopy'}" ;

  if (defined $p->{'orderBy'} && $p->{'orderBy'} =~ m/rid|manufacturer|model|count/ ) {
    $sql .= " order by $p->{'orderBy'}";
  }
  else{
    $sql .= " order by title";
  }
  $sql .= ($p->{'reverse'} eq 'false')?" asc" : " desc";

  #open debug , ">/tmp/debugK"; print debug "p", to_json($p), "\n"; print debug "reverse  $p->{'reverse'} \n"; print debug "sql:$sql\n"; close debug;
  my @recordList = ();
  my @bind_values=();
  my ($resultSize) = $dbh->selectrow_array($sqlCount, undef, @bind_values);
  if ($resultSize>0){
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    while (my $rec = $sth->fetchrow_hashref){
         push @recordList,$rec;
      };
  }
  else{
    $resultSize=0;
  }
  return ($resultSize, \@recordList);
}

=item
sub _eq_record_getInfo {
  my ($dbh, $p) = @_;
  #print debug "_eq_record_getInfo p\t",to_json($p),"\n";
  return if (!$p->{'rid'} || $p->{'rid'} eq "");
  #print debug "rid $p->{'rid'} \n";
  my $rFields = "rid,name,category,container,manufacturer,model,warrantyNote,manufacturerUrl,manualUrl,supplierUrl,generalNote,generalAccessoriesNote,note ";
  my $iFields = "barcode, ";
  my $sql = "select $rFields from eq_record where rid=?";


  my $sth = $dbh->prepare($sql);
  $sth->execute($p->{'rid'} );
  my ($record) = $sth->fetchrow_hashref;
  my ($item,$items);
  if ($p->{'barcode'} &&  $p->{'barcode'} ne ""){
    $sql = "select r.*,i.* from eq_record r inner join eq_item i where r.rid=? && i.barcode=?";
    $sth = $dbh->prepare($sql);
    $sth->execute($p->{'rid'},$p->{'barcode'});
    ($item) = $sth->fetchrow_hashref;
  }
  else  {
    $sql = "select * from eq_item where rid=?";
    $sth = $dbh->prepare($sql);
    $sth->execute($p->{'rid'});
    while (my $i= $sth->fetchrow_hashref){
      push @$items,$i;
    }
  }
  $sth->finish;
  return {record=>$record,item=>$item,items=>$items};
}
=cut

=item
sub search_{
    my ($dbh,$param)=@_; 
    my $eq_solr = Opals::Eq_SolrSearch->new(dbh=>$dbh);
	  $param->{'sfield'} = $param->{'kw'} eq "*" ?"0":$param->{'sfield'};
    my $lQuery = $eq_solr->eq_slr_buildSrchQueryJson($param);
    $param->{'lQuery'}=$lQuery;
    my $rs = $eq_solr->eq_slr_searchJson($param);
    foreach my $rec(@{$rs->{'recordList'}}){
        #$rec->{'recInfo'}=Opals::Equipment::eq_record_getInfo($dbh,{'rid'=>$rec->{'rid'}, 'barcode'=>$rec->{'eq_barcode'},'map'=>0});
        $rec->{'recInfo'}= eq_record_getInfo($dbh,{'rid'=>$rec->{'rid'}, 'barcode'=>$rec->{'eq_barcode'},'map'=>0});
        $rec->{'circInfo'} =  _eq_circ_getItemStatus($dbh,{'barcode'=>$rec->{'eq_barcode'}});
        $rec->{'status'}=$rec->{'circInfo'}->{'status'};
        $rec->{'statusTxt'}=$status_map->{$rec->{'circInfo'}->{'status'}} || "N/A";
    }
    my (@rsAvail,@rsOnloan,@rsMissing) = ((),(),());
    my ($nAvail,$nOnloan,$nMissing) = (0,0,0);
    foreach my $rec(@{$rs->{'recordList'}}){
      if ($param->{'circStatus'} eq 'available' && $rec && $rec->{'status'} == 1){
        push @rsAvail,$rec;
        $nAvail++;
      }
      elsif($param->{'circStatus'} eq 'onloan' && $rec->{'status'}==3){
        push @rsOnloan,$rec;
        $nOnloan++;
      }
      elsif($param->{'circStatus'} eq 'missing' && $rec->{'status'}==11){
        push @rsMissing,$rec;
        $nMissing++;
      }
    }
    if ($param->{'circStatus'} eq 'available'){
        $rs->{'recordList'} = \@rsAvail;
        $rs->{'hits'}=$nAvail;
    }
    elsif($param->{'circStatus'} eq 'onloan'){
        $rs->{'recordList'} = \@rsOnloan;
        $rs->{'hits'}=$nOnloan;
    }
    elsif($param->{'circStatus'} eq 'missing'){
        $rs->{'recordList'} = \@rsMissing;
        $rs->{'hits'}=$nMissing;
    }
    return  $rs;
}
=cut
