/**
 * @license
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import {Subscription} from 'rxjs';
import {CodeOwnerService} from './code-owners-service';
import {ModelLoader} from './code-owners-model-loader';
import {
  CodeOwnersModel,
  PluginStatus,
  Status,
  SuggestionsState,
  SuggestionsType,
  UserRole,
} from './code-owners-model';
import {LitElement, PropertyValues} from 'lit';
import {property, state} from 'lit/decorators';
import {ChangeInfo} from '@gerritcodereview/typescript-api/rest-api';
import {ReportingPluginApi} from '@gerritcodereview/typescript-api/reporting';
import {RestPluginApi} from '@gerritcodereview/typescript-api/rest';
import {CodeOwnerBranchConfigInfo, FetchedFile} from './code-owners-api';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Constructor<T> = new (...args: any[]) => T;

export interface CodeOwnersModelMixinInterface {
  change?: ChangeInfo;
  reporting?: ReportingPluginApi;
  restApi?: RestPluginApi;
  modelLoader?: ModelLoader;
  model?: CodeOwnersModel;

  pluginStatus?: PluginStatus;
  branchConfig?: CodeOwnerBranchConfigInfo;
  userRole?: UserRole;
  areAllFilesApproved?: boolean;
  status?: Status;
  showSuggestions?: boolean;
  allOwnersLoaded?: boolean;
  selectedSuggestionsType?: SuggestionsType;
  selectedSuggestionsFiles?: Array<FetchedFile>;
  selectedSuggestionsState?: SuggestionsState;
  selectedSuggestionsLoadProgress?: string;

  loadPropertiesAfterModelChanged(): void;
}
/**
 * The CodeOwnersMixin adds several properties to a class and translates
 * 'model-property-changed' events from the model to the notifyPath calls.
 * This allows to use properties of the model in observers, calculated
 * properties and bindings.
 * It is guaranteed, that model and modelLoader are set only if change,
 * reporting and restApi properties are set.
 */

export const CodeOwnersModelMixin = <T extends Constructor<LitElement>>(
  superClass: T
) => {
  /**
   * @lit
   * @mixinClass
   */
  class Mixin extends superClass {
    @property({type: Object})
    change?: ChangeInfo;

    @property({type: Object})
    reporting?: ReportingPluginApi;

    @property({type: Object})
    restApi?: RestPluginApi;

    @state()
    pluginStatus?: PluginStatus;

    @state()
    branchConfig?: CodeOwnerBranchConfigInfo;

    @state()
    userRole?: UserRole;

    @state()
    areAllFilesApproved?: boolean;

    @state()
    status?: Status;

    @state()
    showSuggestions?: boolean;

    @state()
    selectedSuggestionsType?: SuggestionsType;

    @state()
    selectedSuggestionsFiles?: Array<FetchedFile>;

    @state()
    selectedSuggestionsState?: SuggestionsState;

    @state()
    selectedSuggestionsLoadProgress?: string;

    private model_?: CodeOwnersModel;

    private subscriptions: Array<Subscription> = [];

    modelLoader?: ModelLoader;

    get model() {
      return this.model_;
    }

    set model(model: CodeOwnersModel | undefined) {
      if (this.model_ === model) return;
      for (const s of this.subscriptions) {
        s.unsubscribe();
      }
      this.subscriptions = [];
      this.model_ = model;
      if (!model) return;
      this.subscriptions.push(
        model.state$.subscribe(s => {
          this.pluginStatus = s.pluginStatus;
        })
      );
      this.subscriptions.push(
        model.state$.subscribe(s => {
          this.branchConfig = s.branchConfig;
        })
      );
      this.subscriptions.push(
        model.state$.subscribe(s => {
          this.userRole = s.userRole;
        })
      );
      this.subscriptions.push(
        model.state$.subscribe(s => {
          this.status = s.status;
        })
      );
      this.subscriptions.push(
        model.state$.subscribe(s => {
          this.areAllFilesApproved = s.areAllFilesApproved;
        })
      );
      this.subscriptions.push(
        model.showSuggestions$.subscribe(s => {
          this.showSuggestions = s;
        })
      );
      this.subscriptions.push(
        model.selectedSuggestionsType$.subscribe(s => {
          this.selectedSuggestionsType = s;
        })
      );
      this.subscriptions.push(
        model.selectedSuggestionsFiles$.subscribe(f => {
          this.selectedSuggestionsFiles = f;
        })
      );
      this.subscriptions.push(
        model.selectedSuggestionsLoadProgress$.subscribe(p => {
          this.selectedSuggestionsLoadProgress = p;
        })
      );
      this.subscriptions.push(
        model.selectedSuggestionsState$.subscribe(s => {
          this.selectedSuggestionsState = s;
        })
      );
      this.loadPropertiesAfterModelChanged();
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    constructor(...args: any[]) {
      super(...args);
    }

    protected override willUpdate(changedProperties: PropertyValues): void {
      super.willUpdate(changedProperties);

      if (
        changedProperties.has('change') ||
        changedProperties.has('restApi') ||
        changedProperties.has('reporting')
      ) {
        if (!this.restApi || !this.change || !this.reporting) {
          this.model = undefined;
          this.modelLoader = undefined;
          return;
        }
        const ownerService = CodeOwnerService.getOwnerService(
          this.restApi,
          this.change
        );
        const model = CodeOwnersModel.getModel(this.change);
        this.modelLoader = new ModelLoader(ownerService, model);
        // Assign model after modelLoader, so modelLoader can be used in
        // the loadPropertiesAfterModelChanged method
        this.model = model;
      }
    }

    protected loadPropertiesAfterModelChanged() {}
  }

  return Mixin as unknown as T & Constructor<CodeOwnersModelMixinInterface>;
};
