#!/usr/bin/perl

use strict;
use CGI;

use Opals::Context;

use Opals::Template qw(
    tmpl_read
    tmpl_write
);
use Opals::Search qw(
 
    srch_F852Default_marc21

);

use Time::localtime;

use Opals::Search qw(
    srch_getMarcImport
);

use Opals::Tb_Record qw(
    
    tb_defRecordIndex_getList
    tb_barcode_getMaxValue

    tb_record_setFlagUpdating
    tb_record_findByRId
    tb_record_add
    tb_record_delete
    
    tb_itemType_getList
    tb_item_findByRId
    tb_item_setFlagUpdating
    tb_item_add
    tb_item_update
    tb_item_delete
    tb_item_deleteByBarcode

    tb_barcode_getList
    tb_isbn_getList
    tb_title_getList

    tb_record_idGen
    tb_isBarcodeExist
    tb_barcode_getMaxDup
    tb_createNextBiggerBc

);

use Opals::Tb_Circulation qw(

    circ_getLoanListByRid
    circ_getItemStatus

);
use Opals::Constant;

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

my $cgi = CGI->new;
my $input = $cgi->Vars();
my ($permission, $cookieList, $template) = tmpl_read(
    {
        dbh             => $dbh,
        cgi             => $cgi,
        tmplFile        => 'txtbk/edit.tmpl',
        reqPermission   => 'tb_record_edit',
    }
);

my $rid         = $input->{'rid'};
my $opt         = $input->{'opt'};
my $zEdit       = $input->{'tbZEdit'};
my $resultId    = $input->{'resultId'};
my @bCode       = ($cgi->param('bcode'));
my @itType      = ($cgi->param('ittype'));
my @lCode       = ($cgi->param('lcode'));
my @price       = ($cgi->param('price'));
my @classNo     = ($cgi->param('classno'));
my @acqDate     = ($cgi->param('acquisitiondate'));
my @distributor = ($cgi->param('distributor'));
my @PONo        = ($cgi->param('pono'));
my @regionCode  = ($cgi->param('rgncode'));
my @districtCode= ($cgi->param('dstcode'));
my @buildingCode= ($cgi->param('bldcode'));
my @importDate  = ($cgi->param('impdate'));
my @budgetCategory    = ($cgi->param('budgetCategory'));
my @vendorCatalogNo   = ($cgi->param('vendorCatalogNo'));
my @delItem     = ($cgi->param('delItem'));

my $defRecordIndexList  = tb_defRecordIndex_getList($dbh, 1);
my $tbItemTypeList    = tb_itemType_getList($dbh);

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

my $recordInfo;
my $itemList;
if ($permission && $permission->{'tb_record_edit'}) {
    if ($opt && $opt eq 'edit'){ #edit from database record - items
        #mark record - items for update
        tb_record_setFlagUpdating($dbh, $rid);
        #tb_item_setFlagUpdating($dbh, $rid);
        #add new updated record-items
        my $retRecAdd = tb_record_add($dbh, $rid, '005', $dateToday);
        foreach my $def(@$defRecordIndexList){
            my $fId= $def->{'fieldId'} . '_' . $def->{'subfield'};
            if ($def->{'repeatable'}){
                my @fVals = ($cgi->param($fId));
                foreach my $f(@fVals){
                    $retRecAdd = tb_record_add($dbh, $rid, $fId, $f);
                }
            }
            elsif($def->{'checkbox'} ){
                my $fVal    = $input->{$fId};
                if ($fVal){
                    $fVal    = $input->{$fId . '_v'};
                    $retRecAdd = tb_record_add($dbh, $rid, $fId, $fVal);
                }
            }
            else{
                if ($fId eq '900_a'){
                    #my $fVal = $input->{$fId};
                    my @fVals = ($cgi->param($fId));
                    my $fVal = join(",", @fVals);
                    $retRecAdd = tb_record_add($dbh, $rid, $fId, $fVal);
                }
                else {
                    my $fVal = $input->{$fId};
                    $retRecAdd = tb_record_add($dbh, $rid, $fId, $fVal);
                }
            }
        }
        for my $i (0 .. $#bCode){
            if ($delItem[$i] eq "1") {
                tb_item_deleteByBarcode($dbh,$rid,$bCode[$i]); 
                next;
            }
            my $params = {
                rid         => $rid,
                barcode     => $bCode[$i],
                typeId      => $itType[$i],
                lCode       => $lCode[$i],
                price       => $price[$i],
                classno     => $classNo[$i],
                acqDate     => $acqDate[$i],
                PONo        => $PONo[$i],
                distributor => $distributor[$i],
                regionCode  => $regionCode[$i],
                districtCode=> $districtCode[$i],
                buildingCode=> $buildingCode[$i],
                importDate  => $importDate[$i],
                budgetCategory=> $budgetCategory[$i],
                vendorCatalogNo=>$vendorCatalogNo[$i]
            };
            my $retItemAdd = tb_item_update($dbh, $params);
        }
        #delete marked update record - items
        tb_record_delete($dbh, $rid,1);    
        #tb_item_delete($dbh, $rid, 1);  
        #get updated record - items for display
        ($rid, $recordInfo) = tb_record_findByRId($dbh,$rid, '1');
        $itemList    = tb_item_findByRId($dbh,$rid);
        my @bcList = ();
        my $j = 0;  
        foreach my $i(@$itemList){
            push @bcList, {
                    i => $j++,
                    barcode => $i->{'barcode'}
                };
            my $ret = circ_getItemStatus($dbh,$i->{'barcode'});
            if ($ret->{'status'} == IT_STAT_ONLOAN){
                $i->{'onLoan'} = 1;
            }
            if ($ret->{'status'} == IT_STAT_LOST){
                $i->{'lost'} = 1;
            }
            if ($ret->{'status'} == ITEM_DAMAGED){
                $i->{'damaged'} = 1;
            }
        }
        $template->param(
            rid             => $rid,
            record          => $recordInfo,
            itemList        => $itemList,
            txtbk_edit      => 1,
            barcodeList     => \@bcList
        );
    }
    elsif ($opt && $opt eq 'zEdit' ){ # edit from z-import databases
        my ($sfIsbn,$sfRecordInfo) =  getMarcImportRecordField($dbh, $resultId);
        my $newrid  = 0; #tb_record_idGen($dbh);
        my $newRecord  = mapRecordFields($dbh, $newrid ,$sfRecordInfo);
        my ($dupIsbn, $dupIsbnList, $dupIsbnRIdList)   = 
            checkDuplication($sfIsbn, tb_isbn_getList($dbh, ''), 'isbn', $rid ,$resultId);
        $template->param(
                zEdit           => 1,
                rid             => $rid,
                zResultId       => $resultId,
                newrid          => $newrid,
                record          => $newRecord,
                dupIsbnRIdList  => $dupIsbnRIdList,
                duplicate       => ($dupIsbn) ? 1:0,
        );
    }
    elsif ($opt && $opt eq 'zSave'){
        my $saveDone = 1;
        my $rid = tb_record_idGen($dbh);
        my $title = $input->{'245_a'};
        my $retRecAdd = tb_record_add($dbh, $rid, '005', $dateToday);
        foreach my $def (@$defRecordIndexList){
            my $fId     = $def->{'fieldId'} . '_' . $def->{'subfield'};
            my $fVal = "";
            if ($def->{'repeatable'}){
                my @fVal = ($cgi->param($fId));
                foreach my $f(@fVal){
                    $retRecAdd = tb_record_add($dbh, $rid, $fId, $f);
                    if ($retRecAdd < 1 || $saveDone < 1){ $saveDone = 0;}
                }
            }
            else {
                $fVal    = $input->{$fId};
                $retRecAdd = tb_record_add($dbh, $rid, $fId, $fVal);
                if ($retRecAdd < 1 || $saveDone < 1)
                    { $saveDone = 0;}
            }
        }
        for my $i (0 .. $#bCode){
            my $params = {
                rid         => $rid,
                barcode     => $bCode[$i],
                typeId      => $itType[$i],
                lCode       => $lCode[$i],
                price       => $price[$i],
                classno     => $classNo[$i],
                acqDate     => $acqDate[$i],
                PONo        => $PONo[$i],
                distributor => $distributor[$i],
                regionCode  => $regionCode[$i],
                districtCode=> $districtCode[$i],
                buildingCode=> $buildingCode[$i],
                importDate  => $importDate[$i],
                budgetCategory=> $budgetCategory[$i],
                vendorCatalogNo=>$vendorCatalogNo[$i]

            };
            my $retItemAdd = tb_item_add($dbh, $params);
            if ($retItemAdd < 1 || $saveDone < 1){ $saveDone = 0;}
        }
        $template->param(
            zSaved      => 1,
            importOK    => 1,
            title       => $title,
        );
        ($rid, $recordInfo) = tb_record_findByRId($dbh,$rid,'1');
        $itemList    = tb_item_findByRId($dbh,$rid);
        my $onLoanList =  circ_getLoanListByRid($dbh,$rid);
            foreach my $ol (@$onLoanList){
                foreach my $i(@$itemList){
                    if ($ol->{'barcode'} eq $i->{'barcode'}){
                        $i->{'onLoan'} = 1;
                    }
                }
            }

        $template->param(
            rid             => $rid,
            record          => $recordInfo,
            itemList        => $itemList,
            txtbk_edit      => 1,
        );
    }
    else{#get record - items from database for edit
        my ($sfIsbn,$sfRecordInfo) =  getMarcImportRecordField($dbh, $resultId);
        my $newrid  = 0; #tb_record_idGen($dbh);
        my $newRecord  = mapRecordFields($dbh, $newrid ,$sfRecordInfo);
        my ($dupIsbn, $dupIsbnList, $dupIsbnRIdList)   = 
            checkDuplication($sfIsbn, tb_isbn_getList($dbh, ''), 'isbn', $rid ,$resultId);
        
        if ($dupIsbn ){
            $template->param(
                rid             => $rid,
                zResultId       => $resultId,
                newrid          => $newrid,
                record          => $newRecord,
                dupIsbnRIdList  => $dupIsbnRIdList,
                duplicate       => 1,
            );
        }
        my @bcList = ();
        if ($rid > 0){
            ($rid, $recordInfo) = tb_record_findByRId($dbh,$rid,'1');
            #$recordInfo = mapRecordFields($dbh, $rid ,$recordInfo);
            $itemList    = tb_item_findByRId($dbh,$rid);
            my $j = 0;
            foreach my $i(@$itemList){
                push @bcList, {
                    i => $j++,
                    barcode => $i->{'barcode'}
                };

                my $ret = circ_getItemStatus($dbh,$i->{'barcode'});
                if ($ret->{'status'} == IT_STAT_ONLOAN){
                    $i->{'onLoan'} = 1;
                }
                if ($ret->{'status'} == IT_STAT_LOST){
                    $i->{'lost'} = 1;
                }
                if ($ret->{'status'} == IT_STAT_DAMAGED){
                    $i->{'damaged'} = 1;
                }
            }
#new holding 

            $template->param(
                rid             => $rid,
                record          => $recordInfo,
                itemList        => $itemList,
                txtbk_edit      => 1,
                barcodeList     => \@bcList
            );
        }
        else{
            $recordInfo = $newRecord;
            $template->param(
                rid             => 0,
                record          => $recordInfo,
                zEdit           => 1,
                zResultId       => $resultId,
            );
        }
    }
}## end permission
my $maxBarcode  = tb_barcode_getMaxValue($dbh,$rid);
my $nextMaxBarcode =  tb_createNextBiggerBc($dbh,$maxBarcode);


    $template->param(
        tbItemTypeList  => $tbItemTypeList, 
        maxBarcode      => $maxBarcode,
        nextBiggerMaxBc => $nextMaxBarcode,
        todayDateTime   => $dateToday,
);
#get default system-library codes
my $default852 = srch_F852Default_marc21($dbh);
my $sCode =  $default852->subfield('a');
my $lCode =  $default852->subfield('b');

$template->param(
    sCode   => $sCode,
    lCode   => $lCode,
);

tmpl_write($dbh, $cgi, $cookieList, $template);

#----------------------------------------------------------------------------------
sub getMarcImportRecordField{
    my ($dbh, $resultId) = @_;
    my $sfInfo;
    my $sfTitle;
    my $sfIsbn;
    my ($tag, $ind1, $ind2, $sfCode, $data);
    if (defined $resultId ){
        my $jsxmlMarc = srch_getMarcImport($dbh, $template->param('curUserId'), $resultId);
        $template->param(
            jsxmlMarc    => $jsxmlMarc,
        );
        my $sfXml;
        my $field;
        my $fId;
        while ($jsxmlMarc =~ s/[\s]*<datafield tag="([\d]{3})" ind1="([\d ])" ind2="([\d ])">(([\s]*<subfield code=".">.*<\/subfield>)*)[\s]*<\/datafield>//) {
            $tag   = $1;
            $ind1  = $2;
            $ind2  = $3;
            $sfXml = $4;
            $field = undef;
            my @subfield = ();
            my ($curfId, $prefId) = ('','');
            while ($sfXml =~ s/[\s]*<subfield code="([\w])">(.*)<\/subfield>// && $tag ne '852') {
                ($sfCode, $data) = ($1, $2);
                $fId = $tag . "_" . $sfCode;
                ($data) || ($data = ' '); # fix empty (sub)field
                $data =~ s/^\s+|\s+$//g;
                push @{$sfInfo->{$fId}}, $data;
                if ($fId eq '020_a'){
                    push @{$sfIsbn} , $data;
                }
                if ($fId eq '245_a'){
                    push @{$sfTitle}, $data;
                }
            }
        }
    }
    return ($sfIsbn, $sfInfo);
}

sub mapRecordFields {
    my $rec_info;
    my ($dbh, $rid, $sfInfo) = @_;
    my @record = ();
    my $order = 0;
    my $myHash;
    my @arr = ();
    my $sql = "SELECT * 
               FROM tb_index_map 
               order by displayOrder ";
    
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    while( my $rec = $sth->fetchrow_hashref){
         if ($rec->{'repeatable'}){
             if ($sfInfo->{$rec->{'fId'}}){
                foreach my $val (@{$sfInfo->{$rec->{'fId'}}}){
                    push @{$myHash->{$rec->{'fId'}}}, { 
                        fVal        => $val,
                        fOrder      => $order,
                        url_link    => ($rec->{'fieldType'} eq '3')?1:0,
                        number      => ($rec->{'fieldType'} eq '4')?1:0,
                        checkbox    => ($rec->{'fieldType'} eq '5')?1:0,
                        };
                    $order++;
                    }
             }
             else {
                 push @{$myHash->{$rec->{'fId'}}}, { 
                    fVal        => '',
                    fOrder      => $order,
                    url_link    => ($rec->{'fieldType'} eq '3')?1:0,
                    number      => ($rec->{'fieldType'} eq '4')?1:0,
                    checkbox    => ($rec->{'fieldType'} eq '5')?1:0,
                    gradeLevel => ($rec->{'fId'} eq '900_a' ) ? 1:0
                };
                $order++;
             }
        }
        $rec_info->{$rec->{'fId'}} = {
            rid         => $rid,
#            fOrder      => $order++,
            fId         => $rec->{'fId'},
            fVal        => $sfInfo->{$rec->{'fId'}}[0],
            fVals       => \@{$myHash->{$rec->{'fId'}}},
            nfVals      => scalar(@{$myHash->{$rec->{'fId'}}}) > 1 ? scalar(@{$myHash->{$rec->{'fId'}}}):1,
            fName       => $rec->{'fieldName'},
            repeatable  => $rec->{'repeatable'},
            required    => $rec->{'required'},
            displayOrder=> $rec->{'displayOrder'},
            url_link    => ($rec->{'fieldType'} eq '3')?1:0,
            number      => ($rec->{'fieldType'} eq '4')?1:0,
            checkbox    => ($rec->{'fieldType'} eq '5')?1:0,
            gradeLevel  => ($rec->{'fId'} eq "900_a")? 1:0

        };
    }
    foreach my $fid (keys %{$rec_info}) {
        push @record, $rec_info->{$fid};
    }

    my  @sortRecByDisplayOrder = sort {$$a{displayOrder} <=> $$b{displayOrder}} @record ;
   
    $sth->finish;
#    return \@record;
    return \@sortRecByDisplayOrder;
}

sub checkDuplication {
   
    my ($importISBNList, $existISBNList, $field, $rid, $resultId) = @_;

    my $dup = 0;
    my @dupList = ();
    
    my @curFieldList = ();
    my @curRidList = ();

    foreach my $item (@{$existISBNList}){
        push @curFieldList, $item->{$field};
        push @curRidList, $item->{rid};
    }
    my %newList = map {$_,1} @{$importISBNList};
    @dupList = grep { $newList {$_}} @curFieldList;
    $dup = scalar(@dupList) > 0 ? 1:0;
    my @dupRIdList = ();
    
    push @dupRIdList,   {
            rid     => 0,
            newRec  => 1,
        };
    foreach my $existField (@{$existISBNList}){
        foreach my $newField(@dupList){
            if ($existField->{$field} eq $newField){
                 push @dupRIdList,   {
                    rid     => $existField->{rid}, 
                    newRec  => 0,
                };
                last;
            }
        }
    }
    foreach my $rec (@dupRIdList){
        $rec->{sel} =  ($rid && $rid == $rec->{'rid'}) ? 1 : ($resultId && $resultId == $rec->{'rid'}) ? 1 : 0,
    }
    return ($dup, \@dupList, \@dupRIdList);
}




