#!/usr/bin/perl -Ilibs -I../www/libs

package API::VehicleLandingPageAdmin;

use strict;
use warnings;
use autodie;
use namespace::autoclean;

use Carp;
use Moose;
use MooseX::NonMoose;
use Try::Tiny;
use ECS::CDN::S3;


extends "API::Controller",
        "SOAP::Server::Parameters";

use API::Config;

use ECS::Vehicle;
use ECS::VehicleConfig;
use ECS::VehicleLandingPage;
use ECS::VehicleSelector;

__PACKAGE__->meta->make_immutable;

###############################################################################

sub index {
    my $self = shift->new({'input' => shift || {}});

    $self->data->{'makes'} = \%ECS::Vehicle::MAKES;

    $self->data->{'templates'} = [ "index.html" ];
    return $self->result;
}

###############################################################################

sub getStepData {
    my $self = shift->new({'input' => shift || {}});

    my $makeID = $self->input->{'makeID'}
        or croak "Missing makeID";
    my $make = $ECS::Vehicle::MAKES{ $makeID }
        or croak "Invalid step";
    my $step = $self->input->{'step'}
        or croak "Missing step";
    croak "Invalid step"
        unless grep { $_ eq $step } @{ $make->{'steps'} };

    $self->data->{'data'}->{'stepData'} = $self->_fetchSteps( $step, $makeID );

    $self->data->{'dataType'} = "json";
    $self->data->{'data'}->{'success'} = 1;
    return $self->result;
}

###############################################################################

sub _fetchSteps {
    my ( $self, $step, $makeID ) = @_;

    my $make = $ECS::Vehicle::MAKES{ $makeID };

    my %where = (
        'makeID' => $makeID,
    );
    my @steps = map { "${_}ID" } @{ $make->{'steps'} };
    for my $step ( @steps ) {
        $where{ $step } = $self->input->{ $step }
            if $self->input->{ $step };
    }

    my $sqlJoin;
    my $sqlOrder = "";
    if( $make->{'type'} eq "vehicleSelector" ) {
        $sqlJoin = qq{
            JOIN vehicleSelector
                USING ( ${step}ID )
            JOIN vehicleConfig
                ON vehicleSelector.makeVehicleConfigID = vehicleConfig.vehicleConfigID
        };
        @where{ qw( 
            yearID
            modelID
            subModelID
            engineID
            bodyTypeID
            bodyCodeID
        ) } = ( 0 ) x 6;
        $sqlOrder = q{
            ORDER BY
                name
        };
    }
    else {
        $sqlJoin = qq{
            JOIN vehicleConfig
                USING ( ${step}ID )
        };
        if($step eq "year") {
            $sqlOrder = q{
                ORDER BY
                    yearID DESC
            };
        } else {
            $sqlOrder = q{
                ORDER BY
                    name
            };
        }
    }

    my $sqlWhere = join " AND ", map { "$_ = ?" } keys %where;
    my $sql = qq{
        SELECT
            ${step}ID   AS ID,
            ${step}Name AS name
        FROM $step
        $sqlJoin
        WHERE
            $sqlWhere
        GROUP BY
            ${step}ID
        $sqlOrder
    };
    my $sth = $self->dbhr->prepare( $sql );
    $sth->execute( values %where );
    return $sth->fetchall_arrayref( {} );
}

###############################################################################

sub getVehicleLandingPage {
    my $self = shift->new({'input' => shift || {}});

    my $makeID = $self->input->{'makeID'}
        or croak "Missing makeID";
    my $make = $ECS::Vehicle::MAKES{ $makeID }
        or croak "Invalid make";
    my $siteID = $self->input->{ 'siteID' }
        or croak "Missing siteID";

    my $site;
    try {
        $site = ECS::Site->fromID( $siteID );
    }
    catch {
        croak "Invalid siteID: $_";
    };

    my %attr = ();
    my @fields = map { "${_}ID" } @{ $make->{'steps'} };
    if( $make->{'type'} eq "vehicleSelector" ) {
        $attr{'join'} = {
            'vehicleSelector' => "makeVehicleConfig",
        };
    }
    else {
        $attr{'join'} = "vehicleConfig";
    }

    my %where = (
        'makeID' => $makeID,
    );
    for my $field ( @fields ) {
        $where{ $field } = $self->input->{ $field } || 0;
    }

    my $vlp;
    my $success = 1;
    try {
        my $vlps = ECS::VehicleLandingPage->search({
            'dbh'    => $site->site_dbhr,
            'search' => [
                \%where,
                \%attr,
            ],
        });
        $vlp = $vlps->[ 0 ];
        $vlp = $vlp->pack if $vlp;
    }
    catch {
        warn "getVehicleLandingPage failed; $_";
        $success = 0;
    };

    $self->data->{'dataType'} = "json";
    $self->data->{'data'}->{'success'} = $success;
    $self->data->{'data'}->{'vlp'} = $vlp;
    return $self->result;
}

###############################################################################

sub save {
    my $self = shift->new({ 'input' => shift || {} });
    my $envelope = pop;

    my $makeID = $self->input->{'makeID'}
        or croak "Missing makeID";
    my $make = $ECS::Vehicle::MAKES{ $makeID }
        or croak "Invalid make";
    my $siteID = $self->input->{ 'siteID' }
        or croak "Missing siteID";

    my $site;
    try {
        $site = ECS::Site->fromID( $siteID );
    }
    catch {
        croak "Invalid siteID: $_";
    };

    my $vehicleLandingPageID = $self->input->{'vehicleLandingPageID'};
    my $imageName = $self->input->{'image'};
    my $description = $self->input->{'description'};
    my $feature = $self->input->{ 'feature' };
    my $h1 = $self->input->{ 'h1' };
    my $title = $self->input->{ 'title' };
    my $enabled = $self->input->{'enabled'};
    my $vehicleConfigID = $self->input->{'vehicleConfigID'};
    my $vehicleSelectorID = $self->input->{'vehicleSelectorID'};
    my $employeeID = $self->input->{ 'employeeID' };

    my $vlp = ECS::VehicleLandingPage->new({
        'dbh'        => $site->site_dbh,
        'employeeID' => $employeeID,
        ( $vehicleLandingPageID
            ? ( 'vehicleLandingPageID' => $vehicleLandingPageID )
            : ()
        ),
    });

    if($make->{'type'} eq "vehicleSelector") {
        $vehicleConfigID = undef;
        $vehicleSelectorID ||= $vlp->vehicleSelectorID;
        $vehicleSelectorID ||= $self->_getVehicleSelectorID( $makeID );
        croak "Missing vehicleSelectorID" unless $vehicleSelectorID;
        $vlp->vehicleSelectorID( $vehicleSelectorID );
    }
    else {
        $vehicleSelectorID = undef;
        $vehicleConfigID ||= $vlp->vehicleConfigID;
        $vehicleConfigID ||= $self->_getVehicleConfigID( $makeID );
        croak "Missing vehicleConfigID" unless $vehicleConfigID;
        $vlp->vehicleConfigID( $vehicleConfigID );
    }

    my $image = try {
        my @parts = $envelope->parts;
        $parts[0]->[0]->bodyhandle->as_string;
    }
    catch { undef };

    my $imagePath = $self->_uploadImage( $image, $imageName );
    $vlp->imagePath( $imagePath )
        if $imagePath;

    $vlp->description( $description );
    $vlp->feature( $feature );
    $vlp->h1( $h1 );
    $vlp->title( $title );
    $vlp->enabled( $enabled ? "YES" : "NO" );

    if( $vlp->vehicleLandingPageID ) {
        $vlp->update;
    }
    else {
        $vlp->insert;
    }

    $self->data->{'dataType'} = "json";
    $self->data->{'data'}->{'success'} = 1;
    return $self->result;
}

###############################################################################

sub _getVehicleConfigID {
    my ($self, $makeID) = @_;

    my $make = $ECS::Vehicle::MAKES{ $makeID }
        or croak "Invalid make";

    my %where = (
        'makeID' => $makeID,
    );
    my @steps = map { "${_}ID" } @{ $make->{'steps'} };
    for my $step ( @steps ) {
        $where{ $step } = $self->input->{ $step } || 0;
    }

    my $rs = ECS::VehicleConfig->search({
        'dbh'    => $self->dbhr,
        'search' => [
            \%where,
        ],
    });

    return unless @{ $rs };

    return $rs->[ 0 ]->vehicleConfigID;
}

###############################################################################

sub _getVehicleSelectorID {
    my ($self, $makeID) = @_;

    my $make = $ECS::Vehicle::MAKES{ $makeID }
        or croak "Invalid make";

    my %where = (
        'makeID'     => $makeID,
        'yearID'     => 0,
        'modelID'    => 0,
        'subModelID' => 0,
        'engineID'   => 0,
        'bodyTypeID' => 0,
        'bodyCodeID' => 0,
    );
    my @steps = map { "${_}ID" } @{ $make->{'steps'} };
    for my $step ( @steps ) {
        $where{ $step } = $self->input->{ $step } || 0;
    }

    my $rs = ECS::VehicleSelector->search({
        'dbh'    => $self->dbhr,
        'search' => [
            \%where,
            {
                'join' => "makeVehicleConfig",
            },
        ],
    });

    return unless @{ $rs };

    return $rs->[ 0 ]->vehicleSelectorID;
}

###############################################################################

sub _uploadImage {
    my ( $self, $image, $imageName ) = @_;

    return unless $image;
    return unless $imageName;

    my $s3 = ECS::CDN::S3->new();
	
    my $container = 'static';

    my $i = 1;
    my $imagePath = "vehicleLandingPage/$imageName";
    while (1) {
        # VLP admin only allows jpg files, so content-type always image/jpeg
        my $c_object_name = $s3->build_path( $container => $imagePath );

       
        eval {
            if ($s3->exists($c_object_name)) {
                $imagePath = "vehicleLandingPage/${i}_$imageName";
                $i++;
                next;
            }
        };

    $s3->post( $c_object_name, $image );
        last;
    }

    return $imagePath;
}

###############################################################################

sub getLogs {
    my $self = shift->new({ 'input' => shift || {} });

    my $vehicleLandingPageID = $self->input->{'vehicleLandingPageID'}
        or croak "Missing vehicleLandingPageID";

    my $rs = ECS::VehicleLandingPage->search( {
        'dbh'    => $self->dbhr,
        'search' => [
            { 'me.vehicleLandingPageID' => $vehicleLandingPageID },
            { 'prefetch' => { 'logs' => "employeeInfo" } },
        ],
    } );
    my $vlp = $rs->[ 0 ]
        or croak "Invalid vehicleLandingPageID";
    my @logs = map { $_->pack } @{ $vlp->logs };

    $self->data->{'dataType'} = "json";
    $self->data->{'data'}->{'success'} = 1;
    $self->data->{'data'}->{'logs'} = \@logs;
    return $self->result;
}

###############################################################################

1;

