#!/usr/bin/perl

#use utf8;
use strict;
use CGI;

use Opals::Context;
use Opals::Template_ajax qw(
    tmpl_read
    tmpl_write
);
use Opals::Session qw(
    SessionHdl_setNote
);

use Opals::Context;use POSIX qw(
    ceil
);
use Opals::MarcXml qw(
    mxml_update
    mxml_newItem
);
use Opals::Ebook qw(
    eb_setMarcXmlRid
);

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

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



my $rid           = $input->{'rid'};
my $bid           = $input->{'ebookId'};

my $marcXml       = $input->{'marcXml'};
my $holdingchange = $input->{'holdingChanges'};
my $isNewItem     = $input->{'isNewItem'};
# parse holdingchange ===> barcode delete, new list
# check error 
# if no then save and error-> return status=>0
# else return error...
my $ssid   = $cgi->cookie('globalSessionID');

my ($permission, $cookie, $template) = tmpl_read(
    {
        dbh             => $dbh,
        cgi             => $cgi,
        tmplFile        => 'ajax/marc21/save.tmpl',
        reqPermission   => 'marc_edit',
    }
);
my $hc=parseHoldingChange($holdingchange);
my $err =validateHoldingChange($dbh,$hc);

if(defined $err && scalar(@$err)){
    $template->param(status=>0,bcErrorList=>$err);
}
else{
    my $delBc=$hc->{'bc_del'};
    my $newBc=$hc->{'bc_new'};
    my $barcodeStats=[];
    my $bcList={};
    foreach my $bc(@$newBc){
        $bcList->{$bc}={status=>'new'};
    }
    foreach my $bc(@$delBc){
        $bcList->{$bc}={status=>'delete'};
    }
    foreach my $c (@{$hc->{'bc_change'}}){
        $bcList->{$c->{'old'}}={status=>'replace',repBc=>$c->{'new'}};
    }

    $rid = mxml_update($dbh,{rid=>$rid, marcXml=>$marcXml, bcList=>$bcList});
    eb_setMarcXmlRid($dbh,$rid,$bid) if(defined $bid && $bid>0);
    $barcodeStats=getBcStatus($dbh,$rid);
    if($isNewItem eq '1'){
        mxml_newItem($dbh, $rid);
    }
    SessionHdl_setNote($dbh, $ssid, "marcEditHitlist",$rid,"saved");
    $template->param(status=>1,rid=>$rid,barcodeStats=>$barcodeStats);
}
tmpl_write($dbh, $cgi, $cookie, $template);

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

#----------------------------------------------------------------------------------------
sub parseHoldingChange{
    my($h)=@_;
    my $hc={bc_new=>[],bc_del=>[],bc_change=>[]};
    foreach my $tag (qw(bc_new bc_del bc_change)){
        my $tmp=$h;
        while($tmp =~ m/<$tag>(.*?)<\/$tag>(.*)/s){
            $tmp=$2;
            if($tag eq 'bc_change'){
               my $c=$1;
               my($newBc ,$oldBc)=("","");
               if($c =~ m/<old>(.*)<\/old>/){
                   $oldBc=$1;
                   if($c =~ m/<new>(.*)<\/new>/g){
                       $newBc=$1;
                       push @{$hc->{$tag}},{old=>$oldBc,new=>$newBc};
                   }
               }
            }
            else{
                push @{$hc->{$tag}},$1;
            }
        }
    }
    
    return $hc; 
}
#----------------------------------------------------------------------------------------
sub validateHoldingChange{
    my($dbh,$hc)=@_;
    my $err=[];

    foreach my $bc (@{$hc->{'bc_new'}}){

        if(isDuplicate($dbh,$bc)){
            push @$err,{barcode=>$bc,errCode=>1};
        }
    }
    foreach my $bc (@{$hc->{'bc_del'}}){
        if(isOnLoan($dbh,$bc)){
            push @$err,{barcode=>$bc,errCode=>2};
        }
        if(isOnHold($dbh,$bc)){
            push @$err,{barcode=>$bc,errCode=>3};
        }
        
    }
    foreach my $c (@{$hc->{'bc_change'}}){
        my($oldBc,$newBc)=($c->{'old'},$c->{'new'});
        if(isOnLoan($dbh,$oldBc)){
            push @$err,{barcode=>,errCode=>3};
        }
        elsif(isOnHold($dbh,$oldBc)){
            push @$err,{barcode=>,errCode=>3};
        }
        else{
            if(isDuplicate($dbh,$newBc)){
                push @$err,{barcode=>,$newBc,errCode=>1};
            }
        }
    }

    return $err;

    
}
#------------------------------------------------------------------------------
sub isDuplicate{
    my($dbh,$bc)=@_;
    my $sth   =$dbh->prepare("select * from opl_item where barcode=?");
    $sth->execute($bc);
    if(my ($b)=$sth->fetchrow_array){
        return 1;
    }
    return 0;
}
#------------------------------------------------------------------------------
sub isOnLoan{
    my($dbh,$bc)=@_;
    my $sth=$dbh->prepare("select * from opl_loan where barcode=? && dateReturn is null");
    $sth->execute($bc);
    if(my ($b)=$sth->fetchrow_array){
        return 1;
    }
    return 0;

}
#------------------------------------------------------------------------------
sub isOnHold{
    my($dbh,$bc)=@_;
    my $sth=$dbh->prepare("select * from opl_hold where barcode=? 
                           && dateExpiry>now() && dateLoan is null && dateCancel is null");
    $sth->execute($bc);
    if(my ($b)=$sth->fetchrow_array){
        return 1;
    }
    return 0;
    
}
#------------------------------------------------------------------------------
sub getBcStatus{
    my($dbh,$rid)=@_;
    my $ret=[];
    my $sth=$dbh->prepare("select i.barcode,i.available,l.idloan from opl_item i left outer join opl_loan l using(barcode) 
                               where l.dateReturn is null && i.barcode not regexp '\_\_\_' && i.rid=?");
    my $sth_d=$dbh->prepare("select status from opl_itemstatus where barcode=? order by id desc limit 1");
    $sth->execute($rid);
    while(my ($bc,$avail,$idloan)=$sth->fetchrow_array){
        my $item={bc=>$bc,onloan=>$idloan, missing=>!$avail};
        $sth_d->execute($bc);
        if(my ($s) =$sth_d->fetchrow_array){
            $item->{"damaged"}=1 if($s==2);
        }
        push @$ret,$item;
    }
   
    return $ret;
}


