#!/usr/bin/perl

#use utf8;
use strict;
use CGI;
use POSIX qw(
    ceil
);
use JSON;
use Opals::Context;
use Opals::Constant;
use Opals::Tb_Record qw(
    tb_record_findByRId
    tb_item_findByRId
    tb_item_findByBarcode
);
use Opals::Tb_Search qw(
    
    search_record
    search_record_byBarcode
    
);

use Opals::Tb_Circulation qw(
    circ_getLoanListByRid
    circ_getItemStatus

);
use Opals::Date qw(
    date_text
);

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


my ($resultSize, $recordList);
my @filterItem = qw(PONumber acqDate acquisitionDate budgetCategory buildingCode distributor i importDate modDate order poNo updating vendorCatalogNo vendorCatalogNumber);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
    my $json ="";
     while (<STDIN>) {
        $json .= $_;
    }
    my $input = decode_json($json);
    my $kw = $input->{'kw'};
    my $sfCode = $input->{'sfield'};
    my $sortAttr    = $input->{'sortAttr'};
    if (!$sortAttr ){
        $sortAttr = '245_a';
    }
    my $sortOrder   = $input->{'sortOrder'} || 0;
    my $pRange = 1;
    my $pSize = 100000;
    my $curPage = 1;
    my $offset = 0;

    if ($kw && $sfCode){
        if ($sfCode eq '852_p'){
            ($resultSize, $recordList) = search_record_byBarcode($dbh, $kw, $offset, $pSize, $sortOrder, $sortAttr);
        }
        else{
            ($resultSize, $recordList) = search_record($dbh, $sfCode, $kw, $offset, $pSize, $sortOrder, $sortAttr);
            if ($resultSize<=0){
                ($resultSize, $recordList) = search_record_byBarcode($dbh, $kw, $offset, $pSize, $sortOrder, $sortAttr);
            }
        }
        if ( $resultSize>0){
            $recordList = getRecordInfo($recordList);
        }
    }
}
print "Content-type: text/plain\n\n";
print  to_json({
      size  => $resultSize,
      list  => $recordList
    });


##########################################################################
#
sub getRecordInfo {
    my ($list) = @_;;
    foreach my $l(@$list){
        $l->{'itemList'} = tb_item_findByRId($dbh,$l->{'rid'});
        foreach my $item(@{$l->{'itemList'}} ){
            foreach my $f (@filterItem) {
                delete $item->{$f};
            }
            $item->{'itemStatus'} = circ_getItemStatus($dbh,$item->{'barcode'}) ;
            if ($item->{'itemStatus'}->{'status'} == IT_STAT_FULL_AVAIL){
                $item->{'status'} = 'IN';
            }
            elsif ($item->{'itemStatus'}->{'status'} == IT_STAT_DAMAGED){
                $item->{'status'} = 'Damaged';
            }
            elsif($item->{'itemStatus'}->{'status'} == IT_STAT_LOST){
                $item->{'status'} = 'Lost';
            }
            elsif($item->{'itemStatus'}->{'status'} == IT_STAT_MISSING){
                $item->{'status'} = 'Missing';
            }
            elsif($item->{'itemStatus'}->{'status'} == IT_STAT_ONLOAN){
                $item->{'status'} = "On Loan";
            }
        }
    }
    return $list;
}


sub search_record_byTitle{

    my ($dbh, $sfCode, $kw, $sortField, $offset, $pSize) = @_;
    my ($sql, $sqlCount, $sqlItems, $sqlICount);

    ($offset >= 0) || ($offset = 0);
    ($pSize  > 0) || ($pSize  = 1);


    $sql        = "SELECT distinct (rid) FROM tb_records r inner join tb_items i using(rid)
                    WHERE MATCH (r.fVal) AGAINST ('+$kw' in boolean mode)  && r.fId = '$sfCode' && r.deleted <> '1' order by r.rid ";
    $sqlCount   = "SELECT COUNT(distinct rid) FROM tb_records r inner join tb_items i using(rid) 
                   WHERE MATCH (fVal) AGAINST ('+$kw' in boolean mode) && fId = '$sfCode' && r.deleted <> '1' ";
    
    my ($resultSize) = $dbh->selectrow_array($sqlCount, undef);
    my $availRange   = $resultSize - $offset + 1;
   
    if ($availRange > $pSize) {
        $availRange = $pSize;
    }
    elsif ($availRange <=0) {
        $availRange = $resultSize % $pSize;
        $availRange = $pSize if ($availRange == 0); 
        $offset = $resultSize - $availRange + 1;
    }
    my @recordList = ();
    my $totalItems=0;

    if ($resultSize > 0){              
        my $query = "$sql LIMIT $offset, $availRange";
        my $sth = $dbh->prepare($query);
        $sth->execute();                
        while(my ($rid) = $sth->fetchrow_array()){
            my ($recId, $recInfo) = tb_record_findByRId($dbh, $rid);
            my ($title,$subTitle, $author, $isbn, $publisher, $pubDate)   = formatRecord(@$recInfo);
            my $itemList = tb_item_findByRId($dbh, $rid);
            my $circInfo ;
            my @itemCircList;
            my $nItemOnLoan = 0;
            my $nItemLost   = 0;
            foreach my $item(@$itemList){
                $circInfo = circ_getItemStatus($dbh,$item->{'barcode'}) ;
                if ($circInfo->{'status'} == IT_STAT_ONLOAN){
                    $nItemOnLoan ++;
                }
                elsif ($circInfo->{'status'} == IT_STAT_LOST){
                    $nItemLost ++;
                }
                my $username ;
                if ($circInfo && $circInfo->{'l_uid'}){
                    my ($userInfo,$guardien) = user_getInformationById($dbh,$circInfo->{'l_uid'});
                    $username = $userInfo->{'firstname'} . " " . $userInfo->{'lastname'} ;
                }
                push @itemCircList, {
                    barcode     => $item->{'barcode'},
                    status      => $circInfo->{'status'},
                    dueDate     => $circInfo->{'l_duedate'} ? date_text($circInfo->{'l_duedate'},0) : "",
                    uid         => $circInfo->{'l_uid'} ? $circInfo->{'l_uid'}: "",
                    username    => $username,
                };
                $totalItems++;
            }

            push @recordList,  {
                rid         => $recId,
                title       => $title,
                author      => $author,
                isbn        => $isbn,
                publisher   => $publisher,
                pubDate     => $pubDate,
                nItems       => scalar(@itemCircList),
                nItemsOnLoan => $nItemOnLoan,
                nItemsAvail  => scalar(@itemCircList) - $nItemOnLoan - $nItemLost,   
                itemList    => \@itemCircList,
            };
        }
        $sth->finish;
    }
    return ($resultSize,$totalItems, \@recordList);
}

sub formatRecord {
 
    my (@record) = @_;
    my ($title, $subTitle, $author, $isbn, $publisher, $pubDate);
    foreach my $f(@record){
        if ($f->{'fId'} eq '245_a'){
            $title = $f->{'fVal'};
        }
        elsif($f->{'fId'} eq '245_b'){
            $subTitle = $f->{'fVal'};
        }
        elsif ($f->{'fId'} eq '100_a'){
            foreach my $a(@{$f->{'fVals'}}){
                $author .= $a->{'fVal'} . " " ;
            }
        }
        elsif($f->{'fId'} eq '020_a'){
            $isbn = $f->{'fVal'};
        }
        elsif($f->{'fId'} eq '260_b'){
            $publisher = $f->{'fVal'};
        }
        elsif($f->{'fId'} eq '260_c'){
            $pubDate = $f->{'fVal'};
        }
    }
    return ($title, $subTitle, $author, $isbn, $publisher, $pubDate);
}


