#!/usr/bin/perl

use strict;
use CGI;

use Opals::Context;

use Time::localtime;

use Opals::Template qw(
    tmpl_read
    tmpl_write
);

use Opals::User qw(

    user_list
    user_getInformationById
);

use Opals::Date qw(
    date_time_text
    date_getDeadLineDateTime
    date_getDeadLineDate

);

use Opals::Equipment qw(
    
    eq_def_getFieldId
    eq_record_findByRId
    eq_item_findByBarcode
    eq_item_findByRId

);

use Opals::Eq_Circulation qw(

    circ_getItemInfo
    circ_getItemStatus
    circ_getNumItemsAvailable
    circ_getRecordInfo
    circ_fillReserve
    circ_placeReserve 
    circ_fillReserve
    circ_cancelReserve
    circ_getUserListReserve
    circ_placeHold
    circ_getReserveId

);

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

my $cgi = CGI->new;
my $input = $cgi->Vars();

#my $op = $input->{'op'};
my ($permission, $cookie, $template) = tmpl_read(
    {
        dbh             => $dbh,
        cgi             => $cgi,
        tmplFile        => 'eqmnt/reserve.tmpl',
        reqPermission   => 'eq_circ_rsrv|eq_circ_rsrv_self',
    }
);

my @cookieList = ($cookie);

my $tm = localtime;
my $todayStr = sprintf("%04d-%02d-%02d %02d:%02d:%02d",$tm->year+1900,($tm->mon)+1,$tm->mday,$tm->hour,$tm->min,$tm->sec);

my $uInput  = $input->{'uInput'};
my $barcode = $input->{'bc'};
my $op      = $input->{'op'};
my @ridArr  = ($cgi->param('rid'));
my @ncrArr  = ($cgi->param('ncr'));
my @reservePeriod = ($cgi->param('reservePeriod'));

my $rid =0;
my $dateExpiry; 

if ($permission && ($permission->{'eq_circ_rsrv_self'} || $permission->{'eq_circ_rsrv'})) {
    #my($uid,$status,$loanOverrid) = getUID();
    my $uid;
    if ($permission->{'circ_rsrv'}) {
        $template->param(circ_rsrv => 1);
        $uid=getUID();
    }
    # self-reserve only
    else {
        $uid = $template->param('curUserId');
    }
    if ($barcode ne ''){
        my $itemInfo = circ_getItemInfo($dbh, $barcode, $uid);
        my $reservePeriod = $itemInfo->{'reservePeriod'};
        $rid = $itemInfo->{'rid'};
        if ($rid && $rid > 0){
            push @ridArr, $rid;
            push @ncrArr, 1;
            push @reservePeriod, $reservePeriod;
        }
    }
    if ($op eq 'placeReserve' && $uid && $uid > 0 && scalar(@ridArr)){
        my @reserveRsList=();
        my ($reserveMsg1, $reserveMsg2, $reserveMsg3) = (0,0,0);
        my ($reserveStatus, $reserveExpiry,$numHold,$holdExpiry) = (0,0,0,0);
        my $numCopyReserve;
        my $length = 24;
        #$dateExpiry = getReserveDateExpiry($length);
        for (my $i=0; $i <scalar(@ridArr); $i++){
            my $recordInfo = circ_getRecordInfo($dbh, $ridArr[$i], $uid);
            my $r = $recordInfo;
            $dateExpiry = getReserveDateExpiry(@reservePeriod[$i]);
            my $reserveId = circ_getReserveId($dbh, $ridArr[$i], $uid);
            my ($reserveExist, $reserveStatus,$revserveExpiry, $numHold, $holdExpiry) = (0,0,"",0,"");
            if ($reserveId){
                $reserveExist = 1;
            }
            else{
                if (! $ncrArr[$i] || $ncrArr[$i] eq '' ){
                    $ncrArr[$i] = 1;
                    $numCopyReserve = 1;
                }
                else{
                    $numCopyReserve = $ncrArr[$i];
                }
                ($reserveStatus,$reserveExpiry,$numHold,$holdExpiry) = doReserve($dbh,$uid,$recordInfo,$numCopyReserve,$dateExpiry);
                if ($numHold == 0){
                    $reserveMsg1 = 1;   }
                elsif ($numHold == $ncrArr[$i]){
                    $reserveMsg2  =1;   }
                else{
                    $reserveMsg3 = 1;   }
            }
            push @reserveRsList, {
                reserveExist    => $reserveExist,
                reserveFail     => $reserveStatus?0:1,
                eqName          => $recordInfo->{'rname'},
                numReserve      => $ncrArr[$i] - $numHold,
                reserveExpiry   => $reserveExpiry,
                reserveHold     => $numHold?1:0,
                numHold         => $numHold,
                holdExpiry      => $holdExpiry, 
                reserveMsg_01   => $reserveMsg1,
                reserveMsg_02   => $reserveMsg2,
                reserveMsg_03   => $reserveMsg3,
                dateExpiry      => $dateExpiry,
            };
        }

        $template->param( 
            reserveRsList   => \@reserveRsList,
        );
        $template->param(
            result  => 1,
        );
    }
    elsif( $op eq 'cancelReserve' ) {
        for (my $i = 0; $i < $input->{'totalid'}; $i++){
            if($input->{'idrsrv' .$i}){
                circ_cancelReserve($dbh,$input->{'idrsrv' .$i});
            }
        }
    }
    if ($uid && $uid >=0){
        getUserInfo($dbh, $uid);
    }
    if ($uid>=0 ) { $template->param(checkid => 1); }

    if (@ridArr && scalar(@ridArr)){
        my @itemList = ();
        for (my $i = 0; $i <scalar(@ridArr); $i++){
            my $recordInfo= getRecordItemListByRId($dbh, $ridArr[$i]);
            push @itemList, {
                rid     => $recordInfo->{'rid'},
                ncr     => $ncrArr[$i],
                reservePeriod =>  $reservePeriod[$i],
                rname   => $recordInfo->{'rname'},
                numItem => $recordInfo->{'numItem'},
            }
        }
        $template->param(
            itemList    => \@itemList
        );
    }
}
tmpl_write($dbh, $cgi, \@cookieList, $template);

#########################################################################
sub getUID{
    my($uid, $status, $loanOverride)=(-1,0,'');
    if ($input->{'uInput'}){
        my @uList = user_list($dbh, $input->{'uInput'},undef);
        if (scalar(@uList) == 1){
            $uid    = $uList[0]->{'uid'};
            $status = $uList[0]->{'status'};
            if ($status == 1){
                $template->param(block => 0);
                @uList[0]->{'block'} = 0;
            }
            else{
                $template->param(block =>1);
            }
            $template->param(uPerson =>1);
        }
        elsif(scalar(@uList)>1){
            for(my $i=0; $i<scalar(@uList); $i++){
                @uList[$i]->{'block'} = @uList[$i]->{'status'}==1?0:1;
            }
            $template->param(uList => \@uList);
        }
        else {#patron not in system
            $template->param(userNotMatch=>1);
        }
        #$template->param(uList => \@uList);
    }
    elsif ($input->{'InputFromList'}){
        $uid = $input->{'InputFromList'};
        my ($uInfo,$ttt) = user_getInformationById($dbh, $uid);
        $status = $uInfo->{'status'};
    }
    else{
        if ($input->{'hiddenid'}){
            $uid    = $input->{'hiddenid'};
        }
        else{
            #$uid = $input->{'uid'};
            $uid = $cgi->cookie('borrower'); }
        my ($uInfo,$ttt) = user_getInformationById($dbh, $uid);
        $status = $uInfo->{'status'};
    }
    if ($uid && $uid >= 0){
        $template->param(hasUser=>1,);   }
    else{
        $template->param(noUser=>1, );    }

    #return ($uid, $status,$loanOverride);
    return ($uid);
}#end sub

sub getUserInfo(){
    my ($dbh, $uid) = @_;
    my ($userInfo, $guardian) = user_getInformationById($dbh, $uid);
    getReservedItemList($dbh, $template, $uid);
    $template->param(
        user_uid        =>  $userInfo->{'uid'},
        hiddenid        =>  $userInfo->{'uid'},
        user_barcode    =>  $userInfo->{'userbarcode'},
        user_username   =>  $userInfo->{'username'},
        user_firstname  =>  $userInfo->{'firstname'},
        user_lastname   =>  $userInfo->{'lastname'},
        homeroom        =>  $userInfo->{'homeroom'},
    );
}

sub getReservedItemList{

    my ($dbh,$template,$uid) = @_;
    my $reserveList = circ_getUserListReserve($dbh,$uid);
    my $order = 0;
    foreach my $r (@$reserveList){
        $r->{'order'} = $order++;
         if ($r->{'dateReserve'}){
            $r->{'dateReserveFormat'} = $r->{'dateReserve'};
            $r->{'dateReserveFormat'}  =~ s/ / \/ /; 
            $r->{'dateReserveFormat_text'} = date_time_text($r->{'dateReserve'}, 0, 'en' );
        }
        if ($r->{'dateExpiry'}){
            $r->{'dateExpiryFormat'} = $r->{'dateExpiry'};
            $r->{'dateExpiryFormat'}  =~ s/ / \/ /; 
            $r->{'dateExpiryFormat_text'} = date_time_text($r->{'dateExpiry'}, 0, 'en' );
        }
        if ($r->{'holdExpiry'}){
            $r->{'holdExpiryFormat'} = $r->{'holdExpiry'};
            $r->{'holdExpiryFormat'}  =~ s/ / \/ /; 
            $r->{'holdExpiryFormat_text'} = date_time_text($r->{'holdExpiry'}, 0, 'en' );
        }
    }
    $template->param(
        reserveList     =>  \@$reserveList,
        numOfReserves   =>  scalar(@$reserveList),
    );
}

sub doReserve{
    
    my($dbh, $uid, $recInfo, $numCopyReserve ,$dateExpiry) = @_;
    my $numHold = 0;
    my $holdExpiry = "";

    my $rid = $recInfo->{'rid'};
    my $reserve = circ_placeReserve($dbh, $uid, $rid, $numCopyReserve, $todayStr, $dateExpiry);
    if (!$reserve){
        return (0, $dateExpiry, $numHold, $holdExpiry);
    }
    my $numItemsAvailable = circ_getNumItemsAvailable($dbh, $rid);
    if ($numItemsAvailable){
        my $idReserve = circ_getReserveId($dbh, $rid, $uid);
        $holdExpiry = getDateExpiry($recInfo->{'holdPeriod'});
        my $loopEnd = $numItemsAvailable < $numCopyReserve?$numItemsAvailable:$numCopyReserve;
        $numHold = $loopEnd;
        for (my $i = 0; $i<$loopEnd; $i++){
            circ_fillReserve($dbh, $uid, $rid);
            circ_placeHold($dbh, $idReserve, $todayStr, $holdExpiry);
        }
        $dateExpiry = $numHold==$numCopyReserve?"":$dateExpiry;
    }
    return (1, $dateExpiry, $numHold, $holdExpiry);
}

sub getRecordItemListByRId{

    #my $eqNameId = eq_def_getFieldId($dbh,{defType=>'record',fname=>'Equipment Name'});
    my ($dbh, $rid) = @_;
    my @recordInfo = ();
    my $rname;
    my ($recId, $recInfo) = eq_record_findByRId($dbh,{recordId=>$rid});
=item    
    foreach my $f (@$recInfo){
        if ($f->{'fId'} == $eqNameId){
            $rname = $f->{'fValue'};
            last;
        }
    }
=cut    
    my $itemList = eq_item_findByRId($dbh,$rid,0);
    my $numItem = 0;
    if ($itemList){
        $numItem = scalar(@$itemList);
    }

    push @recordInfo, {
        rid     => $rid,
        rname   => $recInfo->[0]->{'rname'},
        numItem => $numItem ,
       };

    return $recordInfo[0]; 
    
}

sub getReserveDateExpiry{
    my ($reservePeriod) = @_;
    my $retDate;
    #$retDate = `date -d '$reservePeriod hour' '+%Y-%m-%d %H:%M:%S'`;
    #return $retDate;
    return $retDate = date_getDeadLineDate($reservePeriod, $todayStr);

}

sub getDateExpiry{
    my ($hourPeriod) = @_;
    my $retDate;
    $retDate = `date -d '$hourPeriod hour' '+%Y-%m-%d %H:%M:%S'`;
    return $retDate;
}

