import { NgModule } from 'angular-ts-decorators';
import { INJECTED_CONFIG, INJECTED_FEATURES, INJECTED_ENDPOINTS } from "./constants/injected-values.constant";
import { NAME_PATTERNS } from "./constants/name-patterns.constant";
import * as angular from 'angular';


var quayDependencies: any[] = [
  'chieffancypants.loadingBar',
  'cfp.hotkeys',
  'angular-tour',
  'restangular',
  'angularMoment',
  'mgcrea.ngStrap',
  'ngCookies',
  'ngSanitize',
  'angular-md5',
  'pasvaz.bindonce',
  'ansiToHtml',
  'core-ui',
  'core-config-setup',
  'infinite-scroll',
  'react'
];

if (INJECTED_CONFIG && (INJECTED_CONFIG.MIXPANEL_KEY ||
  INJECTED_CONFIG.MUNCHKIN_KEY ||
  INJECTED_CONFIG.GOOGLE_ANALYTICS_KEY)) {
  quayDependencies.push('angulartics');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.MIXPANEL_KEY) {
  quayDependencies.push('angulartics.mixpanel');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.MUNCHKIN_KEY) {
  quayDependencies.push('angulartics.marketo');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.GOOGLE_ANALYTICS_KEY) {
  quayDependencies.push('angulartics.google.analytics');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.RECAPTCHA_SITE_KEY) {
  quayDependencies.push('vcRecaptcha');
}


/**
 * Module for application-wide configuration.
 */
@NgModule({
  imports: quayDependencies,
  declarations: [],
  providers: []
})
export class QuayRun {

  public run($rootScope: QuayRunScope,
             Restangular: any,
             PlanService: any,
             $http: ng.IHttpService,
             CookieService: any,
             Features: any,
             $anchorScroll: ng.IAnchorScrollService,
             MetaService: any,
             INJECTED_CONFIG: any): void {
    var defaultTitle = INJECTED_CONFIG['REGISTRY_TITLE'] || 'Quay Container Registry';

    // Handle session security.
    Restangular.setDefaultRequestParams(['post', 'put', 'remove', 'delete'],
      {'_csrf_token': (<any>window).__token || ''});

    // Handle session expiration.
    Restangular.setErrorInterceptor(function(response) {
      if (response !== undefined && response.status == 503) {
        (<any>$('#cannotContactService')).modal({});
        return false;
      }

      if (response !== undefined && response.status == 500) {
        window.location.href = '/500';
        return false;
      }

      if (response !== undefined && !response.data) {
        return true;
      }

      var invalid_token = response.data['title'] == 'invalid_token' || response.data['error_type'] == 'invalid_token';
      if (response !== undefined && response.status == 401 &&
        invalid_token &&
        response.data['session_required'] !== false) {
        (<any>$('#sessionexpiredModal')).modal({});
        return false;
      }

      return true;
    });

    // Check if we need to redirect based on a previously chosen plan.
    var result = PlanService.handleNotedPlan();

    // Check to see if we need to show a redirection page.
    var redirectUrl = CookieService.get('quay.redirectAfterLoad');
    CookieService.clear('quay.redirectAfterLoad');

    if (!result && redirectUrl && redirectUrl.indexOf((<any>window).location.href) == 0) {
      (<any>window).location = redirectUrl;
      return;
    }

    $rootScope.$watch('description', function(description: string) {
      if (!description) {
        description = `Hosted private docker repositories. Includes full user management and history. 
                     Free for public repositories.`;
      }

      // Note: We set the content of the description tag manually here rather than using Angular binding
      // because we need the <meta> tag to have a default description that is not of the form "{{ description }}",
      // we read by tools that do not properly invoke the Angular code.
      $('#descriptionTag').attr('content', description);
    });

    // Listen for scope changes and update the title and description accordingly.
    $rootScope.$watch(function() {
      var title = MetaService.getTitle($rootScope.currentPage) || defaultTitle;
      $rootScope.title = title;

      var description = MetaService.getDescription($rootScope.currentPage) || '';
      if ($rootScope.description != description) {
        $rootScope.description = description;
      }
    });

    $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
      $rootScope.current = current.$$route;
      $rootScope.currentPage = current;
      $rootScope.pageClass = '';

      if (!current.$$route) { return; }

      var pageClass = current.$$route.pageClass || '';
      if (typeof pageClass != 'string') {
        pageClass = pageClass(Features);
      }

      $rootScope.pageClass = pageClass;
      $rootScope.newLayout = !!current.$$route.newLayout;
      $rootScope.fixFooter = !!current.$$route.fixFooter;

      $anchorScroll();
    });

    var initallyChecked: boolean = false;
    (<any>window).__isLoading = function() {
      if (!initallyChecked) {
        initallyChecked = true;
        return true;
      }
      return $http.pendingRequests.length > 0;
    };
  }
}


interface QuayRunScope extends ng.IRootScopeService {
  currentPage: any;
  current: any;
  title: any;
  description: string,
  pageClass: any;
  newLayout: any;
  fixFooter: any;
}


// TODO: Make injected values into services and move to NgModule.providers, as constants are not supported in Angular 2
angular
  .module(QuayRun.name)
  .constant('NAME_PATTERNS', NAME_PATTERNS)
  .constant('INJECTED_CONFIG', INJECTED_CONFIG)
  .constant('INJECTED_FEATURES', INJECTED_FEATURES)
  .constant('INJECTED_ENDPOINTS', INJECTED_ENDPOINTS);