# --
# Copyright (C) 2001-2017 OTRS AG, http://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

package Kernel::Modules::AdminCustomerCompany;

use strict;
use warnings;

use Kernel::System::CustomerCompany;
use Kernel::System::ReferenceData;
use Kernel::System::Valid;

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {%Param};
    bless( $Self, $Type );

    # check all needed objects
    for my $Needed (qw(ParamObject DBObject LayoutObject ConfigObject LogObject)) {
        if ( !$Self->{$Needed} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $Needed!" );
        }
    }
    $Self->{CustomerCompanyObject} = Kernel::System::CustomerCompany->new(%Param);
    $Self->{ReferenceDataObject}   = Kernel::System::ReferenceData->new(%Param);
    $Self->{ValidObject}           = Kernel::System::Valid->new(%Param);

    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;

    my $Nav = $Self->{ParamObject}->GetParam( Param => 'Nav' ) || 0;
    my $NavigationBarType = $Nav eq 'Agent' ? 'Companies' : 'Admin';
    my $Search = $Self->{ParamObject}->GetParam( Param => 'Search' );
    $Search
        ||= $Self->{ConfigObject}->Get('AdminCustomerCompany::RunInitialWildcardSearch') ? '*' : '';

    my %GetParam;
    $GetParam{Source} = $Self->{ParamObject}->GetParam( Param => 'Source' ) || 'CustomerCompany';

    # ------------------------------------------------------------ #
    # change
    # ------------------------------------------------------------ #
    if ( $Self->{Subaction} eq 'Change' ) {
        my $CustomerID = $Self->{ParamObject}->GetParam( Param => 'CustomerID' ) || '';
        my %Data = $Self->{CustomerCompanyObject}->CustomerCompanyGet(
            CustomerID => $CustomerID,
        );
        $Data{CustomerCompanyID} = $CustomerID;
        my $Output = $Self->{LayoutObject}->Header();
        $Output .= $Self->{LayoutObject}->NavigationBar(
            Type => $NavigationBarType,
        );
        $Self->_Edit(
            Action => 'Change',
            Nav    => $Nav,
            %Data,
        );
        $Output .= $Self->{LayoutObject}->Output(
            TemplateFile => 'AdminCustomerCompany',
            Data         => \%Param,
        );
        $Output .= $Self->{LayoutObject}->Footer();
        return $Output;
    }

    # ------------------------------------------------------------ #
    # change action
    # ------------------------------------------------------------ #
    elsif ( $Self->{Subaction} eq 'ChangeAction' ) {

        # challenge token check for write action
        $Self->{LayoutObject}->ChallengeTokenCheck();

        my $Note = '';
        my %Errors;
        $GetParam{Source}            = $Self->{ParamObject}->GetParam( Param => 'Source' );
        $GetParam{CustomerCompanyID} = $Self->{ParamObject}->GetParam( Param => 'CustomerCompanyID' );

        for my $Entry ( @{ $Self->{ConfigObject}->Get( $GetParam{Source} )->{Map} } ) {
            $GetParam{ $Entry->[0] } = $Self->{ParamObject}->GetParam( Param => $Entry->[0] ) // '';

            # check mandatory fields
            if ( !$GetParam{ $Entry->[0] } && $Entry->[4] ) {
                $Errors{ $Entry->[0] . 'Invalid' } = 'ServerError';
            }
        }

        if ( !defined $GetParam{CustomerID} ) {
            $GetParam{CustomerID} = $Self->{ParamObject}->GetParam( Param => 'CustomerID' ) || '';
        }

        # check for duplicate entries
        if ( $GetParam{CustomerCompanyID} ne $GetParam{CustomerID} ) {

            # get CustomerCompany list
            my %List = $Self->{CustomerCompanyObject}->CustomerCompanyList(
                Search => $Param{Search},
                Valid  => 0,
            );

            # check duplicate field
            if ( %List && $List{ $GetParam{CustomerID} } ) {
                $Errors{Duplicate} = 'ServerError';
            }
        }

        # if no errors occurred
        if ( !%Errors ) {

            # update group
            if (
                $Self->{CustomerCompanyObject}->CustomerCompanyUpdate(
                    %GetParam,
                    UserID => $Self->{UserID},
                )
                )
            {
                $Self->_Overview(
                    Nav    => $Nav,
                    Search => $Search,
                    %GetParam,
                );
                my $Output = $Self->{LayoutObject}->Header();
                $Output .= $Self->{LayoutObject}->NavigationBar(
                    Type => $NavigationBarType,
                );
                $Output .= $Self->{LayoutObject}->Notify( Info => 'Customer company updated!' );
                $Output .= $Self->{LayoutObject}->Output(
                    TemplateFile => 'AdminCustomerCompany',
                    Data         => \%Param,
                );
                $Output .= $Self->{LayoutObject}->Footer();
                return $Output;
            }
        }

        # something went wrong
        my $Output = $Self->{LayoutObject}->Header();
        $Output .= $Self->{LayoutObject}->NavigationBar(
            Type => $NavigationBarType,
        );
        $Output .= $Self->{LayoutObject}->Notify( Priority => 'Error' );

        # set notification for duplicate entry
        if ( $Errors{Duplicate} ) {
            $Output .= $Self->{LayoutObject}->Notify(
                Priority => 'Error',
                Info     => "CustomerCompany $GetParam{CustomerID} already exists!.",
            );
        }
        $Self->_Edit(
            Action => 'Change',
            Nav    => $Nav,
            Errors => \%Errors,
            %GetParam,
        );
        $Output .= $Self->{LayoutObject}->Output(
            TemplateFile => 'AdminCustomerCompany',
            Data         => \%Param,
        );
        $Output .= $Self->{LayoutObject}->Footer();
        return $Output;
    }

    # ------------------------------------------------------------ #
    # add
    # ------------------------------------------------------------ #
    elsif ( $Self->{Subaction} eq 'Add' ) {
        $GetParam{Name} = $Self->{ParamObject}->GetParam( Param => 'Name' );
        my $Output = $Self->{LayoutObject}->Header();
        $Output .= $Self->{LayoutObject}->NavigationBar(
            Type => $NavigationBarType,
        );
        $Self->_Edit(
            Action => 'Add',
            Nav    => $Nav,
            %GetParam,
        );
        $Output .= $Self->{LayoutObject}->Output(
            TemplateFile => 'AdminCustomerCompany',
            Data         => \%Param,
        );
        $Output .= $Self->{LayoutObject}->Footer();
        return $Output;
    }

    # ------------------------------------------------------------ #
    # add action
    # ------------------------------------------------------------ #
    elsif ( $Self->{Subaction} eq 'AddAction' ) {

        # challenge token check for write action
        $Self->{LayoutObject}->ChallengeTokenCheck();

        my $Note = '';
        my %Errors;
        my $CustomerCompanyKey = $Self->{ConfigObject}->Get( $GetParam{Source} )->{CustomerCompanyKey};
        my $CustomerCompanyID;

        for my $Entry ( @{ $Self->{ConfigObject}->Get( $GetParam{Source} )->{Map} } ) {
            $GetParam{ $Entry->[0] } = $Self->{ParamObject}->GetParam( Param => $Entry->[0] ) // '';

            # check mandatory fields
            if ( !$GetParam{ $Entry->[0] } && $Entry->[4] ) {
                $Errors{ $Entry->[0] . 'Invalid' } = 'ServerError';
            }

            # save customer company key for checking duplicate
            if ( $Entry->[2] eq $CustomerCompanyKey ) {
                $CustomerCompanyID = $GetParam{ $Entry->[0] };
            }
        }

        # get CustomerCompany list
        my %List = $Self->{CustomerCompanyObject}->CustomerCompanyList(
            Search => $Param{Search},
            Valid  => 0,
        );

        # check duplicate field
        if ( %List && $List{$CustomerCompanyID} ) {
            $Errors{Duplicate} = 'ServerError';
        }

        # if no errors occurred
        if ( !%Errors ) {

            # add company
            if (
                $Self->{CustomerCompanyObject}->CustomerCompanyAdd(
                    %GetParam,
                    UserID => $Self->{UserID},
                )
                )
            {
                $Self->_Overview(
                    Nav    => $Nav,
                    Search => $Search,
                    %GetParam,
                );
                my $Output = $Self->{LayoutObject}->Header();
                $Output .= $Self->{LayoutObject}->NavigationBar(
                    Type => $NavigationBarType,
                );
                $Output .= $Self->{LayoutObject}->Notify( Info => 'Customer company added!' );
                $Output .= $Self->{LayoutObject}->Output(
                    TemplateFile => 'AdminCustomerCompany',
                    Data         => \%Param,
                );
                $Output .= $Self->{LayoutObject}->Footer();
                return $Output;
            }
        }

        # something went wrong
        my $Output = $Self->{LayoutObject}->Header();
        $Output .= $Self->{LayoutObject}->NavigationBar(
            Type => $NavigationBarType,
        );
        $Output .= $Self->{LayoutObject}->Notify( Priority => 'Error' );

        # set notification for duplicate entry
        if ( $Errors{Duplicate} ) {
            $Output .= $Self->{LayoutObject}->Notify(
                Priority => 'Error',
                Info     => "CustomerCompany $CustomerCompanyID already exists!.",
            );
        }
        $Self->_Edit(
            Action => 'Add',
            Nav    => $Nav,
            Errors => \%Errors,
            %GetParam,
        );
        $Output .= $Self->{LayoutObject}->Output(
            TemplateFile => 'AdminCustomerCompany',
            Data         => \%Param,
        );
        $Output .= $Self->{LayoutObject}->Footer();
        return $Output;
    }

    # ------------------------------------------------------------
    # overview
    # ------------------------------------------------------------
    else {
        $Self->_Overview(
            Nav    => $Nav,
            Search => $Search,
            %GetParam,
        );
        my $Output = $Self->{LayoutObject}->Header();
        $Output .= $Self->{LayoutObject}->NavigationBar(
            Type => $NavigationBarType,
        );

        $Output .= $Self->{LayoutObject}->Output(
            TemplateFile => 'AdminCustomerCompany',
            Data         => \%Param,
        );

        $Output .= $Self->{LayoutObject}->Footer();
        return $Output;
    }
}

sub _Edit {
    my ( $Self, %Param ) = @_;

    $Self->{LayoutObject}->Block(
        Name => 'Overview',
        Data => \%Param,
    );

    $Self->{LayoutObject}->Block( Name => 'ActionList' );
    $Self->{LayoutObject}->Block(
        Name => 'ActionOverview',
        Data => \%Param,
    );

    $Self->{LayoutObject}->Block(
        Name => 'OverviewUpdate',
        Data => \%Param,
    );

    # shows header
    if ( $Param{Action} eq 'Change' ) {
        $Self->{LayoutObject}->Block( Name => 'HeaderEdit' );
    }
    else {
        $Self->{LayoutObject}->Block( Name => 'HeaderAdd' );
    }

    $Param{'ValidOption'} = $Self->{LayoutObject}->BuildSelection(
        Data       => { $Self->{ValidObject}->ValidList(), },
        Name       => 'ValidID',
        SelectedID => $Param{ValidID},
    );

    for my $Entry ( @{ $Self->{ConfigObject}->Get( $Param{Source} )->{Map} } ) {
        if ( $Entry->[0] ) {
            my $Block = 'Input';

            # build selections or input fields
            if ( $Self->{ConfigObject}->Get( $Param{Source} )->{Selections}->{ $Entry->[0] } ) {
                my $OptionRequired = '';
                if ( $Entry->[4] ) {
                    $OptionRequired = 'Validate_Required';
                }

                # build ValidID string
                $Block = 'Option';
                $Param{Option} = $Self->{LayoutObject}->BuildSelection(
                    Data =>
                        $Self->{ConfigObject}->Get( $Param{Source} )->{Selections}
                        ->{ $Entry->[0] },
                    Name  => $Entry->[0],
                    Class => $OptionRequired . ' ' .
                        ( $Param{Errors}->{ $Entry->[0] . 'Invalid' } || '' ),
                    Translation => 0,
                    SelectedID  => $Param{ $Entry->[0] },
                    Max         => 35,
                );

            }
            elsif ( $Entry->[0] =~ /^CustomerCompanyCountry/i ) {
                my $OptionRequired = '';
                if ( $Entry->[4] ) {
                    $OptionRequired = 'Validate_Required';
                }

                # build Country string
                my $CountryList = $Self->{ReferenceDataObject}->CountryList();

                $Block = 'Option';
                $Param{Option} = $Self->{LayoutObject}->BuildSelection(
                    Data         => $CountryList,
                    PossibleNone => 1,
                    Sort         => 'AlphanumericValue',
                    Name         => $Entry->[0],
                    Class        => $OptionRequired . ' ' .
                        ( $Param{Errors}->{ $Entry->[0] . 'Invalid' } || '' ),
                    SelectedID => defined( $Param{ $Entry->[0] } ) ? $Param{ $Entry->[0] } : 1,
                );
            }
            elsif ( $Entry->[0] =~ /^ValidID/i ) {
                my $OptionRequired = '';
                if ( $Entry->[4] ) {
                    $OptionRequired = 'Validate_Required';
                }

                # build ValidID string
                $Block = 'Option';
                $Param{Option} = $Self->{LayoutObject}->BuildSelection(
                    Data  => { $Self->{ValidObject}->ValidList(), },
                    Name  => $Entry->[0],
                    Class => $OptionRequired . ' ' .
                        ( $Param{Errors}->{ $Entry->[0] . 'Invalid' } || '' ),
                    SelectedID => defined( $Param{ $Entry->[0] } ) ? $Param{ $Entry->[0] } : 1,
                );
            }
            else {
                $Param{Value} = $Param{ $Entry->[0] } || '';
            }

            # show required flag
            if ( $Entry->[4] ) {
                $Param{MandatoryClass} = 'class="Mandatory"';
                $Param{StarLabel}      = '<span class="Marker">*</span>';
                $Param{RequiredClass}  = 'Validate_Required';
            }
            else {
                $Param{MandatoryClass} = '';
                $Param{StarLabel}      = '';
                $Param{RequiredClass}  = '';
            }

            # show required flag
            if ( $Entry->[7] ) {
                $Param{ReadOnlyType} = 'readonly="readonly"';
            }
            else {
                $Param{ReadOnlyType} = '';
            }

            # add form option
            if ( $Param{Type} && $Param{Type} eq 'hidden' ) {
                $Param{Preferences} .= $Param{Value};
            }
            else {
                $Self->{LayoutObject}->Block(
                    Name => 'PreferencesGeneric',
                    Data => {
                        Item => $Entry->[1],
                        %Param
                    },
                );
                $Self->{LayoutObject}->Block(
                    Name => "PreferencesGeneric$Block",
                    Data => {
                        %Param,
                        Item         => $Entry->[1],
                        Name         => $Entry->[0],
                        Value        => $Param{ $Entry->[0] },
                        InvalidField => $Param{Errors}->{ $Entry->[0] . 'Invalid' } || '',
                    },
                );
                if ( $Entry->[4] ) {
                    $Self->{LayoutObject}->Block(
                        Name => "PreferencesGeneric${Block}Required",
                        Data => {
                            Name => $Entry->[0],
                        },
                    );
                }
            }
        }
    }
    return 1;
}

sub _Overview {
    my ( $Self, %Param ) = @_;

    $Self->{LayoutObject}->Block(
        Name => 'Overview',
        Data => \%Param,
    );

    $Self->{LayoutObject}->Block( Name => 'ActionList' );
    $Self->{LayoutObject}->Block(
        Name => 'ActionSearch',
        Data => \%Param,
    );

    # get writable data sources
    my %CustomerCompanySource = $Self->{CustomerCompanyObject}->CustomerCompanySourceList(
        ReadOnly => 0,
    );

    # only show Add option if we have at least one writable backend
    if ( scalar keys %CustomerCompanySource ) {
        $Param{SourceOption} = $Self->{LayoutObject}->BuildSelection(
            Data       => { %CustomerCompanySource, },
            Name       => 'Source',
            SelectedID => $Param{Source} || '',
        );

        $Self->{LayoutObject}->Block(
            Name => 'ActionAdd',
            Data => \%Param,
        );
    }

    $Self->{LayoutObject}->Block(
        Name => 'OverviewHeader',
        Data => {},
    );

    my %List = ();

    # if there are any registries to search, the table is filled and shown
    if ( $Param{Search} ) {
        my %List = $Self->{CustomerCompanyObject}->CustomerCompanyList(
            Search => $Param{Search},
            Valid  => 0,
        );
        $Self->{LayoutObject}->Block(
            Name => 'OverviewResult',
            Data => \%Param,
        );

        # get valid list
        my %ValidList = $Self->{ValidObject}->ValidList();

        if ( !$Self->{ConfigObject}->Get( $Param{Source} )->{Params}->{ForeignDB} ) {
            $Self->{LayoutObject}->Block( Name => 'LocalDB' );
        }

        # if there are results to show
        if (%List) {
            for my $ListKey ( sort { $List{$a} cmp $List{$b} } keys %List ) {

                my %Data = $Self->{CustomerCompanyObject}->CustomerCompanyGet( CustomerID => $ListKey );
                $Self->{LayoutObject}->Block(
                    Name => 'OverviewResultRow',
                    Data => {
                        %Data,
                        Search => $Param{Search},
                        Nav    => $Param{Nav},
                    },
                );

                if ( !$Self->{ConfigObject}->Get( $Param{Source} )->{Params}->{ForeignDB} ) {
                    $Self->{LayoutObject}->Block(
                        Name => 'LocalDBRow',
                        Data => {
                            Valid => $ValidList{ $Data{ValidID} },
                            %Data,
                        },
                    );
                }

            }
        }

        # otherwise it displays a no data found message
        else {
            $Self->{LayoutObject}->Block(
                Name => 'NoDataFoundMsg',
                Data => {},
            );
        }
    }

    # if there is nothing to search it shows a message
    else
    {
        $Self->{LayoutObject}->Block(
            Name => 'NoSearchTerms',
            Data => {},
        );
    }
    return 1;
}

1;
