use utf8;
use warnings; no warnings "redefine";
use strict;
use Dbase::Globals qw(bignum content find_descr get_kunde
	name_kunde name_dienst find_dienst list_descr map_descr get_descr);
use Dbase::Help qw(DoFn DoT DoSelect qquote);
use Loader qw(line_printer);

my $long = !bignum();

sub acct_info ($$$$$$;$) {
	my($jjmm,$tt,$quelle,$dienst,$ziel,$knd,$aks) = @_;
	$aks ||= 0;
	line_printer(0);

	if($knd ne "*" and $knd ne "-") {
		my $kd = get_kunde($knd);
		unless($kd) {
			print STDERR "Kunde '$knd' unbekannt!\n";
			return undef;
		}
		$knd = $kd;
	}
	my($ovx,$ojjmm,$ott,$oquelle,$odienst,$oziel) = @_;
	my $oldf = $|; $|=1;
	$ovx="";
	my($cmd,$cmd1,$cmd2,$cmd3,$cmd2a,$pr1,$pr2,$prl);
	my($rtt,$rjjmm,$rkunde,$rquelle,$rdienst,$rziel,$rtxt);
	my($itt,$ijjmm,$ikunde,$iquelle,$idienst,$iziel,$itxt);
	my($nline);
	my($ibytes,$ipack);
	my($j1,$j2,$t1,$t2,$didpr,$prhead,$xspc,$yspc,$zspc,$xxspc,$yyspc,$zzspc);
	my($bytes,$pakete,$bpak,$ppakete,$pbytes);
	my($arr);
	my(@subkunde,$has, $line);
	my($res);
	my($prseq,$isdndienst,$workdienst,$genldienst,$verzdienst,$plazdienst);
	my(%dienst, %ziel);
	my($rhash,$rseq,$prhash,$ihash,$iseq);

	$cmd1 = "select readonly acct.`hash`,acct.seq,acct.bytes,acct.pakete,acct.jjmm,acct.tt,acct.kunde,acct.quelle,acct.dienst,acct.dest, acctassoc.info";
	$cmd2 = " from acct left join acctassoc on acct.`hash`=acctassoc.`hash` and acct.seq=acctassoc.seq"; $cmd2a = "where";
	$cmd3 = "";
	$pr1 = "%1s "; $pr2 = '$hastar,'; $prl = 2;

	$isdndienst = find_dienst "isdn" || -1;
	$workdienst = find_dienst "arbeit" || -1;
	$verzdienst = find_dienst "verzug" || -1;
	$genldienst = find_dienst "general";
	$plazdienst = find_dienst "platz" || -1;

	if($knd eq "-") {
		$knd = "";
	} elsif($knd eq "*") {
		$cmd3 .= ",acct.kunde";
		$pr1 .= "%-10s "; $pr2 .= 'name_kunde($rkunde),'; $prl += 11;
	} elsif($knd != 0) {
		$cmd2 .= " $cmd2a kunde = $knd"; $cmd2a = "and";
	}


	if($jjmm eq "-" or $jjmm eq "") {
		$jjmm = "";
	} elsif($jjmm =~ /^(\d{4,6})?([=-])(\d{4,6})?$/) {
		$jjmm = ($2 eq "=") ? "*" : "";
		$j1 = $1; $j2 = $3;

		if($j1 =~ /^\d{4,5}$/) { $j1 += 190000; }
		if($j2 =~ /^\d{4,5}$/) { $j2 += 190000; }

		if($j1 =~ /^\d{6}$/) {
			$cmd2.= " $cmd2a jjmm >= $j1"; $cmd2a = "and";
		}

		if($j2 =~ /^\d{6}$/) {
			if($j1 !~ /^\d{6}$/) { ## DATABASE_BUG
				$cmd2.= " $cmd2a jjmm > 0"; $cmd2a = "and";
			}
			$cmd2.= " $cmd2a jjmm <= $j2"; $cmd2a = "and";
		}
	}
	if($jjmm eq "*") {
		$cmd3 .= ",acct.jjmm";
		$pr1 .= "%6s "; $pr2 .= '$rjjmm,'; $prl += 7;
	} elsif($jjmm ne "") {
		if($jjmm =~ /^\d{4,5}$/) {
			$jjmm += 190000;
		}
		if($jjmm =~ /^\d{6}$/) {
			$cmd2.= " $cmd2a jjmm = $jjmm"; $cmd2a = "and";
			$j1 = $j2 = $jjmm;
		}
	}
	
	if($tt eq "-" or $tt eq "") {
		$tt = "";
		$t1 = 1; $t2 = 31;
	} elsif($tt =~ /^(\d\d?)?([=-])(\d\d?)?$/) {
		$tt = ($2 eq "=") ? "*" : "";
		$t1 = $1; $t2 = $3;
		if($t1 =~ /^\d\d?$/) {
			if($t1 <= $t2 or $t2 eq "" or $j1 == $j2) {
				$cmd2.= " $cmd2a tt >= $t1"; $cmd2a = "and";
			}
		} else {
			$t1 = 1;
		}
		if($t2 =~ /^\d\d?$/) {
			if($t1 <= $t2 or $t1 eq "" or $j1 == $j2) {
				$cmd2.= " $cmd2a tt <= $t2"; $cmd2a = "and";
			}
		} else {
			$t2 = 31;
		}
	}
	if($tt eq "*") {
		$cmd3 .= ",acct.tt";
		$pr1 .= "%02d "; $pr2 .= '$rtt,'; $prl += 3;
		$t1 = 1; $t2 = 31;
	} elsif($tt ne "") {
		$cmd2 .= " $cmd2a tt = $tt"; $cmd2a = "and";
		$t1 = $t2 = $tt;
	}

	if($quelle eq "-") {
		$quelle = "";
	} elsif($quelle eq "*") {
		$cmd3 .= ",acct.quelle";
		$pr1 .= "%-10s "; $pr2 .= 'get_descr("quelle",$rquelle),'; $prl += 11;
	} elsif($quelle ne "") {
		$cmd2 .= " $cmd2a quelle = $quelle"; $cmd2a = "and";
	}

	if($dienst eq "-") {
		$dienst = "";
	} elsif($dienst eq "*") {
		$cmd3 .= ",acct.dienst";
		$pr1 .= "%-10s "; $pr2 .= '$dienst{$rdienst},'; $prl += 11;
		DoSelect {
			my($num,$bla) = @_;
			$dienst{$num} = $bla;
		} "select id,name from dienst";
	} elsif($dienst ne "") {
		$cmd2 .= " $cmd2a dienst = $dienst"; $cmd2a = "and";
		$dienst{$dienst} = name_dienst $dienst;
	}

	if($ziel eq "-") {
		$ziel = "";
	} elsif($dienst ne "" and $ziel eq "*") {
		$cmd3 .= ",acct.dest";
		$pr1 .= "%-10s "; $pr2 .= '($ziel{(($dienst eq "*") ? $rdienst : $dienst),$rziel} or $ziel{$rziel}),'; $prl += 11;
		if($dienst eq "*") {
			while(($a,$b)=each %dienst) {
				list_descr($b, 0,"", sub {
					my($name,$num,$bla,$info) = @_;
					$ziel{$a,$num} = $bla;
				});
			}
		} elsif($dienst ne "-") {
			list_descr($dienst{$dienst}, 0,"", sub {
				my($name,$num,$bla,$info) = @_;
				$ziel{$dienst,$num} = $bla;
			});
		}
		list_descr( "ziel", 0, "", sub {
			my($name,$num,$bla,$info) = @_;
			$ziel{$num} = $bla;
		});
	} elsif($ziel ne "") {
		$cmd2 .= " $cmd2a acct.dest = $ziel"; $cmd2a = "and";
	}

	$cmd3 =~ s/^,/ order by /;

	$pr1 .= "%10s %13s";
	$pr1 .= "  %-15s" unless $aks & 2;
	$pr1 .= "\n";
	$pr2 .= '$ppakete,$pbytes';
	$pr2 .= ',$prhash' unless $aks & 2;
	$prl += 10+1+13+2;
	$prl += 15 unless $aks & 2;

	my($hastar) = 0; # compiler warning...

	my($minfixed) = 60;
	my($minfixxed) = 35;
	$xxspc = $xspc = " "x($prl-$minfixed);
	$yyspc = $yspc = " "x($minfixed-$prl);
	$zzspc = $zspc = " "x($prl-$minfixed+$minfixxed);
	$xxspc =~ s/ /-/g;
	$yyspc =~ s/ /-/g;
	$zzspc =~ s/ /-/g;

	my %eqneu;
	DoSelect {
		my($dienst,$berechne) = @_;
		$eqneu{$dienst} = $berechne if defined $berechne;
	} "select dienst,berechne from tarifeq";

# PRSEQ 0:Volumen, 1:Einheiten, 3:Arbeit, 2: Plattenplatz
	my(%dhash); 
	my $isdienst = sub {
		my($xdienst) = @_;
		return $dhash{$xdienst} if defined $dhash{$xdienst};
		my($xxdienst) = $xdienst;
		do {
			$dhash{$xxdienst} = 1, return 1 if $xdienst == $isdndienst;
			$dhash{$xxdienst} = 2, return 2 if $xdienst == $plazdienst;
			$dhash{$xxdienst} = 3, return 3 if $xdienst == $workdienst;
			$dhash{$xxdienst} = 3, return 3 if $xdienst == $verzdienst;
			$dhash{$xxdienst} = 3, return 3 if $xdienst == $genldienst;
			$xdienst = $eqneu{$xdienst};
		} while(defined $xdienst);
		return 0;
	};

	my $pr = sub {
		my($hastar);
		unless($aks & 2 or $didpr) {
			$didpr = 1;
			print $Db::pr_fh <<END;

END
# PRSEQ 0:Volumen, 1:Einheiten, 3:Arbeit, 2: Plattenplatz
			print $Db::pr_fh <<END if $prseq == 2;
Speicherplatz ----------$zzspc-----
${prhead}    Anzahl         Bytes  Acc#
END
			print $Db::pr_fh <<END if $prseq == 3;
Einrichtungskosten/Sonstiges $zzspc
${prhead}    Anzahl       Aufwand  Acc#
END
			print $Db::pr_fh <<END if $prseq == 1;
Telekomgebühren -------$zzspc------
${prhead}Verbindgen     Einheiten  Acc#
END
			print $Db::pr_fh <<END if $prseq == 0;
Volumenabhängige Kosten $zzspc-----
${prhead}    Pakete         Bytes  Acc#
END
			print $Db::pr_fh <<END;
$zzspc-----------------------------
END
		}
		$ppakete = $pakete;
		$pbytes = $bytes;

		my($dosum,$rrtxt);

		$hastar = "+";

		if(content($rtxt)) {
			$rrtxt = $rtxt;
		} else {
			$rrtxt = "";
		}
		if($pbytes == 0) { $pbytes = "-"; } else { $pbytes =~ s/^\+//; }
		if($ppakete == 0) { $ppakete = "-"; } else { $ppakete =~ s/^\+//; }
		if($nline == 1) {
			$prhash = "$rhash-$rseq";
		} else {
			$prhash = "$nline Datensätze";
		}
		eval "printf \$Db::pr_fh \"$pr1\",$pr2";
		die $@ if $@;
		print $Db::pr_fh "  $rrtxt\n" if $rrtxt ne "";
	};

	$cmd = $cmd1 . $cmd2 . $cmd3;
	print STDERR "$cmd\n";

	$line = 0; print STDERR "\r        Fetching detailed accounting data\r";
	my(@rrf);
	my %xplatz;

	$res = DoT($cmd, sub {
		my($arr) = $_[0];
		$line++; print STDERR "  $line\r" if !($line % 100);
		push @rrf, $arr;
	});

	if($res =~ /^\d/) {
		$prseq = 0;
		$didpr = 0;
		while($prseq <= 3) {
			$line = 0; print STDERR "\r        Analyzing accounting data, seq $prseq     \r";
			$prhead = "T ";
			$rkunde = "start"; $prhead .= "Kunde      " if $knd eq "*";
			$rjjmm = "start"; $prhead .= "Monat  " if $jjmm eq "*";
			$rtt = "start"; $prhead .= "TT " if $tt eq "*";
			$rquelle = "start"; $prhead .= "Quelle     " if $quelle eq "*";
			$rdienst = "start"; $prhead .= "Dienst     " if $dienst eq "*";
			$rziel = "start"; $prhead .= "Ziel       " if $ziel eq "*";
			$rtxt = "start";

			foreach $arr(@rrf) {
				$line++; print STDERR "  $line\r" if !($line % 100);
				($ihash,$iseq,$ibytes,$ipack,$ijjmm,$itt,$ikunde,$iquelle,$idienst,$iziel,$itxt) = @$arr;
				next if $prseq != &$isdienst($idienst);

				if($itt <= 31) {
					if($t1 > $t2) { ## Bereich überschneidet wohl eine Monatsgrenze: ignoriere die "Reste"
						next if $j1 == $ijjmm and $itt < $t1;
						next if $j2 == $ijjmm and $itt > $t2;
					} else {
						next if $itt < $t1;
						next if $itt > $t2;
					}
				}

				# Re-init if start, or if a managed field changes.
				# GRR
				{
				no warnings "uninitialized";
				if($aks & 1 or ($long ? ($pakete or $bytes) : ($pakete or $bytes)) and (
	($rtxt    ne $itxt                      ) or
	($rjjmm   ne $ijjmm   and $jjmm   eq "*") or
	($rtt     ne $itt     and $tt     eq "*") or
	($rquelle ne $iquelle and $quelle eq "*") or
	($rkunde  ne $ikunde  and $knd    eq "*") or
	($rdienst ne $idienst and $dienst eq "*") or
	($rziel   ne $iziel   and $ziel   eq "*"))) {
					&$pr() if $rjjmm ne "start";
                    $bytes  = bignum(0); $pakete = bignum(0);
					$nline = 0;
				}
				}
				$nline++; $rhash = $ihash; $rseq = $iseq;
				$bytes   += $ibytes;
				$pakete  += $ipack;
				$rjjmm    = $ijjmm;
				$rtt      = $itt;
				$rkunde   = $ikunde;
				$rquelle  = $iquelle;
				$rdienst  = $idienst;
				$rziel    = $iziel;
				$rtxt     = $itxt;
			}
			$ijjmm = "last";
			&$pr() if $rjjmm ne "start";
		} continue {
			$prseq++;
			$didpr = 0;
		}
	} elsif($res eq "empty") {
		print "Keine Verkehrsdaten gefunden                 \n";
	} else {
		print "Fehler: $res                   \n";
	}
	print STDERR "\r" . (" " x 75) . "\r";
	$|=$oldf;
}

1;
