package SaleReport::ReportLib;

use Data::Dumper;

use Date::Calc;
use URI::Escape;

use lib '/app/tools/common/lib';
use Common::Util qw(moneyize commify);
use Common::Client;
use Common::RSApp;

use lib '/usr/local/chart_director/lib';
use perlchartdir;

use vars qw(@ISA @EXPORT @EXPORT_OK);
@EXPORT    = qw(GetPieChart TableDataToHashRef CreateTableXML);
@EXPORT_OK = qw();
@ISA       = 'Exporter';

# -------------------------------------------------
# CONSTANTS: use them, love them, enjoy them
# -------------------------------------------------
use constant BASE_URL => "/app/reports";

use constant PIE_IMG_DIR => "/app/data/charts";
use constant PIE_IMG_URL => "/images/charts";

# these are dialed in pretty tight
use constant {
    PIE_SIZE_X      => 180,
    PIE_SIZE_Y      => 90,
    PIE_CENTER_X    => 90,
    PIE_CENTER_Y    => 40,
    PIE_RADIUS      => 85,
    PIE_VIEW_ANGLE  => 65,
    PIE_DEPTH       => 10,
    PIE_START_ANGLE => 195,
};

# use constant LINE_COLOR => 0xc0c0c0;
use constant LINE_COLOR => 0xffffff;
use constant PIE_COLORS => [
    0x669999,    # teal
    0xCC99CC,    # lavender
    0x996633,    # light brown
    0x5aaa5a,    # green
    0xb3c8d9,    # light blue
    0x336699,    # blue
    0x86a880,    # sea foam green
    0x333366,    # royal blue
    0x999999,    # grey
    0x663333,    # brown/red/purple
    0xffffb8,    # pale yellow
    0xa0bdc4,    # light blue
    0x594330,    # green olive brown
    0xb8bc9c,    # tan grey beige
];

sub GetPieChart {
    my %args = @_;

    my $labels         = $args{labels};
    my $clickable_ids  = $args{label_ids};
    my $data           = $args{data};
    my $image_map_link = $args{image_map_link};
    my $base_image_src = $args{image_src};
    my $chart_num      = $args{chart_num};

    my $currencySymbol = '&#' . ord( Common::Client::Current()->Locale()->currencyFormat()->symbol() ) . ';';
    my $thousands      = Common::Client::Current()->Locale()->numericFormat()->thousands();
    my $decimal        = Common::Client::Current()->Locale()->numericFormat()->decimal();

    # Create a PieChart object of size X x Y pixels
    my $c = new PieChart( PIE_SIZE_X, PIE_SIZE_Y );

    # Set the center of the pie at (100, 100) and the radius to 80 pixels
    $c->setPieSize( PIE_CENTER_X, PIE_CENTER_Y, PIE_RADIUS );

    # Draw the pie in 3D, at a 60 degree angle
    # set#d(depth, view angle) -1 = auto depth
    $c->set3D( PIE_DEPTH, PIE_VIEW_ANGLE );

    # set the new colors
    $c->setColor( $perlchartdir::LineColor, LINE_COLOR );
    $c->setColors2( $perlchartdir::DataColor, PIE_COLORS );

    # add a legend box where the top left corner is at (135, 10) and set font to arial size 8
    #addLegend(x-coord, y-coord, +vert/-hor, font, font size)
    #my $legendBox = $c->addLegend(185, 30, 0, "arial.ttf", 8);
    #my $legendBox = $c->addLegend(30, 105, 0, "arial.ttf", 8);
    #$legendBox->setCols(2);

    # display percent and name in legend
    #$legendBox->setText("{percent|0}% - {label}");

    # modify the label format for the sectors to $nnnK (pp.pp%)
    $c->setLabelFormat(" ");

    # set start angle at 0 (default)
    #$c->setStartAngle(15);
    $c->setStartAngle(PIE_START_ANGLE);

    #$c->setLabelLayout($perlchartdir::SideLayout);
    #$c->setLabelStyle()->setBackground($perlchartdir::SameAsMainColor, $perlchartdir::Transparent, 1);
    # $c->setLineColor($perlchartdir::SameAsMainColor, 0x0);
    # $c->setLineColor(LINE_COLOR);

    #	$c->setLabelFormat("{label}\n{percent|0}%");

    #Set the pie data and the pie labels
    $c->setData( $data, $labels );

    # $c->setExplode(0);

    # these are used to build the URL in the image map
    $c->addExtraField($clickable_ids);

    #Explode the 1st sector (index = 0)
    #$c->setExplode(0);

    #Create the image and save it in a temporary location
    my $chart_url;
    my $chart_image_src;

    # this is done because chart director uses the process
    # id to establish a unique image name, but this breaks down
    # with more than one chart per request, so the caller maintains
    # its own chart counter and here we use that info to create
    # a truly unique image name for the chart.
    if ( !$base_image_src ) {
        $chart_url = $c->makeTmpFile( PIE_IMG_DIR, 1 );
        $chart_image_src = PIE_IMG_URL . "/$chart_url";
    } else {

        # create another unique temporary file name
        #
        # from:
        # 	$base_image_src = "/images/charts/1783168761482.gif";
        #
        # we want to call:
        # 	makeChart("/app/data/charts/1783168761482_1.gif");
        #
        # and then set:
        # 	$chart_image_src = "/images/charts/1783168761482_1.gif"

        # insert a counter number after the name
        $chart_url = $base_image_src;
        $chart_url =~ s/(_\d)?\.gif$/\_$chart_num\.gif/;

        my $new_image_path;
        ( $new_image_path = $chart_url ) =~ s|^.+/([^/]+\.gif)$|$1|;
        $new_image_path = PIE_IMG_DIR . "/" . $new_image_path;
        $c->makeChart($new_image_path);
        $chart_image_src = $chart_url;
    }

    #Create an image map for the chart
    # !!! This needs to be localized.
    # So, exactly how?   This looks like it is taking some sort of formatting hints.
    # I doubt it will work in any other form that 'normal'.
    # What if the {value} field has already been formatted?
    #
    # !!! This is just working off on the info in the 'data' arg.
    # Which has to be just 'raw' numeric data.
    # So we are relying on the built-in formatting magic of the chart library.
    # ... which means that we may be hosed.
    #
    #	my $imageMap = $c->getHTMLImageMap(BASE_URL, $image_map_link."{field0}", "title='{label} - {percent|1}% &lt;br&gt;\${value|2,.}'");

    # Construct the formatting string for our money.
    #

    my $imageMap = $c->getHTMLImageMap(
        BASE_URL,
        $image_map_link . "{field0}",
        "title='{label} - {percent|1"
          . $thousands
          . $decimal
          . "}% &lt;br&gt;"
          . $currencySymbol
          . "{value|2"
          . $thousands
          . $decimal . "}'"
    );

    #Create an image map for the legend

# NOT MORE LEGENDS, we're going to build our own
# my $legendImageMap = $legendBox->getHTMLImageMap("demoapp", $image_map_link."{label}", "alt='{label} - {percent}% \n\${value}' title='{label} - {percent}% \n\${value}'");

    my $legend_xml = GetLegendXML(
        labels         => $labels,
        data           => $data,
        image_map_link => $image_map_link,
        label_ids      => $clickable_ids,
    );

    # return { image_src => $chart_image_src, image_map => $imageMap.$legendImageMap};
    return { image_src => $chart_image_src, image_map => $imageMap, legend_xml => $legend_xml };
}

sub GetLegendXML {
    my %args = @_;

    my $labels         = $args{labels};
    my $data           = $args{data};
    my $image_map_link = $args{image_map_link};
    my $clickable_ids  = $args{label_ids};

    # Calculate the total first, so we can output meaningful percentages
    #
    my $total = 0;
    for ( my $i = 0 ; $i < scalar @$data ; $i++ ) {
        $total += $$data[$i];
    }

    # Generate the legend XML.
    # Note that we are respecting the order the data is in... in other
    # words, we don't re-sort it in here.
    #
    my $xml = [];
    for ( my $i = 0 ; $i < scalar @$data ; $i++ ) {
        $xml->[$i]->{'Color'} = sprintf( "#%x", (PIE_COLORS)->[$i] );
        $xml->[$i]->{'Label'} = $$labels[$i];

        #		$xml->[$i]->{'Value'} = moneyize($$data[$i]);
        $xml->[$i]->{'Value'} = Common::Client::Current()->Locale()->formatMoney( $$data[$i] );

        if ( $total > 0 ) {

            #			$xml->[$i]->{'Percent'} = sprintf("%.1f%", $$data[$i] / $total * 100);
            $xml->[$i]->{'Percent'} = Common::Client::Current()->Locale()->formatNumber( sprintf( "%.1f%", $$data[$i] / $total * 100 ) );
        } else {
            $xml->[$i]->{'Percent'} = "0%";
        }

        $xml->[$i]->{'Link'} = $clickable_ids->[$i] ? BASE_URL . "?" . $image_map_link . $clickable_ids->[$i] : 'NONE';

    }

    return $xml;
}

sub CreateTableXML {
    my %args        = @_;
    my $data        = $args{data};
    my $labels      = $args{labels};
    my $field_order = $args{order} || [qw(Rank PrevRank ProductInfo ArtistInfo Units Revenue Data)];

    my $table = {};
    my @rows  = ();
    my $tag;

    # let's figure out the header row
    $tag = "HeaderRow";
    my $tmp_row_data = $data->[0];
    my $header_row   = [];
    foreach my $field (@$field_order) {
        if ( exists $tmp_row_data->{$field} ) {
            my $cell_href = {};
            if ( $field eq 'Data' && @$labels ) {
                my $count = 0;
                foreach my $data_val ( @{ $tmp_row_data->{$field} } ) {
                    my $tmp_label = {};
                    $tmp_label->{Key}   = $field;
                    $tmp_label->{Value} = $labels->[$count];
                    push @$header_row, $tmp_label;
                    $count++;
                }
            } else {
                $cell_href->{Key}   = $field;
                $cell_href->{Value} = $field;
                push @$header_row, $cell_href;
            }
        }
    }
    push @{ $table->{$tag} }, { Cell => $header_row };

    $tag = "DataRow";
    foreach my $row_href (@$data) {
        my @cells = ();
        foreach my $field (@$field_order) {
            next if ( !exists $row_href->{$field} );

            my $href = {};
            my $val  = $row_href->{$field};
            $href->{Key} = $field;

            # hashref
            if ( $field eq 'ProductInfo' || $field eq 'ArtistInfo' ) {
                $href->{$field} = $row_href->{$field};
                push @cells, $href;
            }

            # arrayref
            elsif ( $field eq 'Data' ) {
                foreach my $data_val ( @{ $row_href->{$field} } ) {
                    my $tmp_cell = {};
                    $tmp_cell->{Key}   = $field;
                    $tmp_cell->{Value} = $data_val;
                    push @cells, $tmp_cell;
                }
            }

            # scalar
            else {
                $href->{Value} = $val;

                if ( $field =~ /rank/i && $val =~ /^\d+$/ ) {
                    $href->{IntValue} = sprintf( "%05d", int($val) );
                } elsif ( $val =~ /^\d+\.\d\d$/ ) {
                    $href->{Value} = moneyize($val);
                } elsif ( $val =~ /^\d+$/ ) {
                    $href->{Value} = commify($val);
                }
                push @cells, $href;
            }
        }
        push @{ $table->{$tag} }, { Cell => \@cells };
    }
    return $table;
}

sub TableDataToHashRef {
    my $data      = shift;
    my $list_href = {};

    my $first = 1;
    foreach my $row_data (@$data) {
        $tag = "DataRow";

        if ($first) {
            $first = 0;
            $tag   = "HeaderRow";
        }
        my $new_hash = {};

        my @cells = ();
        my $count = 0;
        foreach my $val (@$row_data) {
            my $new_val = $val;

            # convert dates
            if ( $new_val =~ /\d{8}/ ) {
                $new_val = Date::Calc::Month_to_Text( substr( $val, 4, 2 ) );
            }

            my $href = {};
            $href->{Key}   = $data->[0]->[$count];
            $href->{Value} = $new_val;

            if ( $href->{key} =~ /title/i ) {
                $href->{EncodedValue} = uri_escape( $href->{Value} );
            }

            if ( $href->{Key} =~ /rank/i && $href->{Value} =~ /^\d+$/ ) {
                $href->{IntValue} = sprintf( "%05d", int( $href->{Value} ) );
            }

            if ( $href->{Value} =~ /^\d+\.\d\d$/ ) {
                $href->{Value} = commify( $href->{Value} );
            }

            push @cells, $href;
            $count++;
        }
        $new_hash->{Cell} = \@cells;
        push @{ $list_href->{$tag} }, $new_hash;
    }

    return $list_href;
}

sub ConvertFormatParam {
    my $param = shift;

    # convert "Albums" to "album"
    $param =~ s/^(.*)s$/lc($1)/e;

    return $param;
}

sub AddTopServiceCol {
    my $data = shift;

    my $headings = $$data->[0];

    my $count = 0;
    foreach my $row ( @{$$data} ) {

        # skip the row headings
        if ( $count == 0 ) {
            $count++;
            next;
        }

        my @revenues = ();
        my $index    = 0;
        foreach my $cell (@$row) {

            # capture all the revenue data
            if ( $cell =~ /^\d+\.\d\d$/ ) {
                push @revenues, { revenue => $cell, index => $index };
            }
            $index++;
        }

        # find the second biggest, the biggest is total revenue
        my $max_href = ( sort { $b->{revenue} <=> $a->{revenue} } @revenues )[1];
        push @$row, $$data->[0]->[ $max_href->{index} ] . " " . $max_href->{revenue};
    }

    push @{ $$data->[0] }, "Top Service";
}

###
1;    # Play nicely;
###
