/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  ChangeInfo,
  NumericChangeId,
  ChangeStatus,
  ReviewerState,
  AccountId,
  AccountInfo,
  GroupInfo,
  Hashtag,
} from '../../api/rest-api';
import {Model} from '../model';
import {Finalizable} from '../../services/registry';
import {RestApiService} from '../../services/gr-rest-api/gr-rest-api';
import {define} from '../dependency';
import {select} from '../../utils/observable-util';
import {
  ReviewInput,
  ReviewerInput,
  AttentionSetInput,
  RelatedChangeAndCommitInfo,
} from '../../types/common';
import {getUserId} from '../../utils/account-util';
import {getChangeNumber} from '../../utils/change-util';

export const bulkActionsModelToken =
  define<BulkActionsModel>('bulk-actions-model');

export enum LoadingState {
  NOT_SYNCED = 'NOT_SYNCED',
  LOADING = 'LOADING',
  LOADED = 'LOADED',
}
export interface BulkActionsState {
  loadingState: LoadingState;
  selectableChangeNums: NumericChangeId[];
  selectedChangeNums: NumericChangeId[];
  allChanges: Map<NumericChangeId, ChangeInfo>;
}

const initialState: BulkActionsState = {
  loadingState: LoadingState.NOT_SYNCED,
  selectedChangeNums: [],
  selectableChangeNums: [],
  allChanges: new Map(),
};

export class BulkActionsModel
  extends Model<BulkActionsState>
  implements Finalizable
{
  constructor(private readonly restApiService: RestApiService) {
    super(initialState);
  }

  public readonly selectedChangeNums$ = select(
    this.state$,
    bulkActionsState => bulkActionsState.selectedChangeNums
  );

  public readonly totalChangeCount$ = select(
    this.state$,
    bulkActionsState => bulkActionsState.allChanges.size
  );

  public readonly loadingState$ = select(
    this.state$,
    bulkActionsState => bulkActionsState.loadingState
  );

  public readonly selectedChanges$ = select(this.state$, bulkActionsState => {
    const result = [];
    for (const changeNum of bulkActionsState.selectedChangeNums) {
      const change = bulkActionsState.allChanges.get(changeNum);
      if (change) result.push(change);
    }
    return result;
  });

  toggleSelectedChangeNum(changeNum: NumericChangeId) {
    this.getState().selectedChangeNums.includes(changeNum)
      ? this.removeSelectedChangeNum(changeNum)
      : this.addSelectedChangeNum(changeNum);
  }

  addSelectedChangeNum(changeNum: NumericChangeId) {
    const current = this.getState();
    if (!current.selectableChangeNums.includes(changeNum)) {
      throw new Error(
        `Trying to add change ${changeNum} that is not part of bulk-actions model`
      );
    }
    const selectedChangeNums = [...current.selectedChangeNums];
    selectedChangeNums.push(changeNum);
    this.setState({...current, selectedChangeNums});
  }

  removeSelectedChangeNum(changeNum: NumericChangeId) {
    const current = this.getState();
    if (!current.selectableChangeNums.includes(changeNum)) {
      throw new Error(
        `Trying to remove change ${changeNum} that is not part of bulk-actions model`
      );
    }
    const selectedChangeNums = [...current.selectedChangeNums];
    const index = selectedChangeNums.findIndex(item => item === changeNum);
    if (index === -1) return;
    selectedChangeNums.splice(index, 1);
    this.updateState({selectedChangeNums});
  }

  clearSelectedChangeNums() {
    this.updateState({selectedChangeNums: []});
  }

  selectAll() {
    const current = this.getState();
    this.updateState({
      selectedChangeNums: Array.from(current.allChanges.keys()),
    });
  }

  abandonChanges(
    reason?: string,
    // errorFn is needed to avoid showing an error dialog
    errFn?: (changeNum: NumericChangeId) => void
  ): Promise<Response | undefined>[] {
    const current = this.getState();
    return current.selectedChangeNums.map(changeNum => {
      if (!current.allChanges.get(changeNum))
        throw new Error('invalid change id');
      const change = current.allChanges.get(changeNum)!;
      if (change.status === ChangeStatus.ABANDONED) {
        return Promise.resolve(new Response());
      }
      return this.restApiService.executeChangeAction(
        getChangeNumber(change),
        change.actions!.abandon!.method,
        '/abandon',
        undefined,
        {message: reason ?? ''},
        () => errFn && errFn(getChangeNumber(change))
      );
    });
  }

  voteChanges(reviewInput: ReviewInput) {
    const current = this.getState();
    return current.selectedChangeNums.map(changeNum => {
      const change = current.allChanges.get(changeNum)!;
      if (!change) throw new Error('invalid change id');
      return this.restApiService.saveChangeReview(
        getChangeNumber(change),
        'current',
        reviewInput,
        () => {
          throw new Error();
        }
      );
    });
  }

  addReviewers(
    changedReviewers: Map<ReviewerState, (AccountInfo | GroupInfo)[]>,
    reason: string
  ): Promise<Response>[] {
    const current = this.getState();
    const changes = current.selectedChangeNums.map(
      changeNum => current.allChanges.get(changeNum)!
    );
    return changes.map(change => {
      const reviewersNewToChange: ReviewerInput[] = [
        ReviewerState.REVIEWER,
        ReviewerState.CC,
      ].flatMap(state =>
        this.getNewReviewersToChange(change, state, changedReviewers)
      );
      if (reviewersNewToChange.length === 0) {
        return Promise.resolve(new Response());
      }
      const attentionSetUpdates: AttentionSetInput[] = reviewersNewToChange
        .filter(reviewerInput => reviewerInput.state === ReviewerState.REVIEWER)
        .map(reviewerInput => {
          return {
            // TODO: Once Groups are supported, filter them out and only add
            // Accounts to the attention set, just like gr-reply-dialog.
            user: reviewerInput.reviewer as AccountId,
            reason,
          };
        });
      const reviewInput: ReviewInput = {
        reviewers: reviewersNewToChange,
        ignore_automatic_attention_set_rules: true,
        add_to_attention_set: attentionSetUpdates,
      };
      return this.restApiService.saveChangeReview(
        getChangeNumber(change),
        'current',
        reviewInput
      );
    });
  }

  addHashtags(hashtags: Hashtag[]): Promise<Hashtag[]>[] {
    const current = this.getState();
    return current.selectedChangeNums.map(changeNum =>
      this.restApiService
        .setChangeHashtag(changeNum, {
          add: hashtags,
        })
        .then(responseHashtags => {
          // Once we get server confirmation that the hashtags were added to the
          // change, we are updating the model's ChangeInfo. This way we can
          // keep the page state (dialog status) but use the updated change info
          // naturally.

          // refetch the current state since other changes may have been updated
          // since the promises were launched.
          const current = this.getState();
          const nextState = {
            ...current,
            allChanges: new Map(current.allChanges),
          };
          nextState.allChanges.set(changeNum, {
            ...nextState.allChanges.get(changeNum)!,
            hashtags: responseHashtags,
          });
          this.setState(nextState);
          return responseHashtags;
        })
    );
  }

  async sync(changes: (ChangeInfo | RelatedChangeAndCommitInfo)[]) {
    const basicChanges = new Map(changes.map(c => [getChangeNumber(c), c]));
    let currentState = this.getState();
    const selectedChangeNums = currentState.selectedChangeNums.filter(
      changeNum => basicChanges.has(changeNum)
    );
    const selectableChangeNums = changes.map(c => getChangeNumber(c));
    this.updateState({
      loadingState: LoadingState.LOADING,
      selectedChangeNums,
      selectableChangeNums,
      allChanges: new Map(),
    });

    if (changes.length === 0) {
      return;
    }
    const changeDetails =
      await this.restApiService.getDetailedChangesWithActions(
        changes.map(c => getChangeNumber(c))
      );
    currentState = this.getState();
    // Return early if sync has been called again since starting the load.
    if (selectableChangeNums !== currentState.selectableChangeNums) return;
    const allDetailedChanges: Map<NumericChangeId, ChangeInfo> = new Map();
    for (const detailedChange of changeDetails ?? []) {
      allDetailedChanges.set(detailedChange._number, detailedChange);
    }
    this.setState({
      ...currentState,
      loadingState: LoadingState.LOADED,
      allChanges: allDetailedChanges,
    });
  }

  private getNewReviewersToChange(
    change: ChangeInfo,
    state: ReviewerState,
    changedReviewers: Map<ReviewerState, (AccountInfo | GroupInfo)[]>
  ): ReviewerInput[] {
    return (
      changedReviewers
        .get(state)
        ?.filter(account => !change.reviewers[state]?.includes(account))
        .map(account => {
          return {state, reviewer: getUserId(account)};
        }) ?? []
    );
  }
}
