import {
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnInit,
  Output,
  ViewChild,
} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {Builder, ByteBuffer} from 'flatbuffers';
import {ErrorResponse} from '@org_frc971/scouting/webserver/requests/messages/error_response_generated';
import {
  StartMatchAction,
  StartMatchActionT,
  NoShowActionT,
  NoShowAction,
  ScoreType,
  StageType,
  Submit2024Actions,
  MobilityAction,
  MobilityActionT,
  PenaltyAction,
  PenaltyActionT,
  PickupNoteAction,
  PickupNoteActionT,
  PlaceNoteAction,
  PlaceNoteActionT,
  RobotDeathAction,
  RobotDeathActionT,
  EndMatchAction,
  EndMatchActionT,
  ActionType,
  Action,
  ActionT,
} from '@org_frc971/scouting/webserver/requests/messages/submit_2024_actions_generated';
import {Match} from '@org_frc971/scouting/webserver/requests/messages/request_all_matches_response_generated';
import {
  MatchListRequestor,
  ActionsSubmitter,
} from '@org_frc971/scouting/www/rpc';
import {ActionHelper, ConcreteAction} from './action_helper';
import * as pako from 'pako';

type Section =
  | 'Team Selection'
  | 'Init'
  | 'Pickup'
  | 'Place'
  | 'Endgame'
  | 'Dead'
  | 'Review and Submit'
  | 'QR Code'
  | 'Success';

type CompType = 'PreScouting' | 'Practice' | 'Regular';

// TODO(phil): Deduplicate with match_list.component.ts.
const COMP_LEVELS = ['qm', 'ef', 'qf', 'sf', 'f'] as const;
export type CompLevel = typeof COMP_LEVELS[number];

// TODO(phil): Deduplicate with match_list.component.ts.
const COMP_LEVEL_LABELS: Record<CompLevel, string> = {
  qm: 'Qualifications',
  ef: 'Eighth Finals',
  qf: 'Quarter Finals',
  sf: 'Semi Finals',
  f: 'Finals',
};

// The maximum number of bytes per QR code. The user can adjust this value to
// make the QR code contain less information, but easier to scan.
const QR_CODE_PIECE_SIZES = [150, 300, 450, 600, 750, 900];

// The default index into QR_CODE_PIECE_SIZES.
const DEFAULT_QR_CODE_PIECE_SIZE_INDEX = QR_CODE_PIECE_SIZES.indexOf(450);

// The actions that are purely used for tracking state. They don't actually
// have any permanent meaning and will not be saved in the database.
const STATE_ACTIONS: ActionType[] = [
  ActionType.EndAutoPhaseAction,
  ActionType.EndTeleopPhaseAction,
];

@Component({
  selector: 'app-entry',
  templateUrl: './entry.ng.html',
  styleUrls: ['../app/common.css', './entry.component.css'],
})
export class EntryComponent implements OnInit {
  // Re-export the type here so that we can use it in the `[value]` attribute
  // of radio buttons.
  readonly COMP_LEVELS = COMP_LEVELS;
  readonly COMP_LEVEL_LABELS = COMP_LEVEL_LABELS;
  readonly QR_CODE_PIECE_SIZES = QR_CODE_PIECE_SIZES;
  readonly ScoreType = ScoreType;
  readonly StageType = StageType;
  readonly ActionT = ActionT;
  readonly ActionType = ActionType;
  readonly NoShowActionT = NoShowActionT;
  readonly StartMatchActionT = StartMatchActionT;
  readonly MobilityActionT = MobilityActionT;
  readonly PickupNoteActionT = PickupNoteActionT;
  readonly PlaceNoteActionT = PlaceNoteActionT;
  readonly RobotDeathActionT = RobotDeathActionT;
  readonly PenaltyActionT = PenaltyActionT;
  readonly EndMatchActionT = EndMatchActionT;

  section: Section = 'Team Selection';
  @Input() matchNumber: number = 1;
  @Input() teamNumber: string = '1';
  @Input() setNumber: number = 1;
  @Input() compLevel: CompLevel = 'qm';
  @Input() compType: CompType = 'Regular';
  @Input() skipTeamSelection = false;

  @ViewChild('header') header: ElementRef;

  matchList: Match[] = [];

  actionHelper: ActionHelper;
  actionList: ActionT[] = [];
  progressMessage: string = '';
  errorMessage: string = '';
  autoPhase: boolean = true;
  mobilityCompleted: boolean = false;
  // TODO(phil): Come up with a better name here.
  selectedValue = 0;
  endGameAction: StageType = StageType.kMISSING;
  noteIsTrapped: boolean = false;
  endGameSpotlight: boolean = false;

  nextTeamNumber = '';

  matchStartTimestamp: number = 0;
  penalties: number = 0;

  teamSelectionIsValid = false;

  // When the user chooses to generate QR codes, we convert the flatbuffer into
  // a long string. Since we frequently have more data than we can display in a
  // single QR code, we break the data into multiple QR codes. The data for
  // each QR code ("pieces") is stored in the `qrCodeValuePieces` list below.
  // The `qrCodeValueIndex` keeps track of which QR code we're currently
  // displaying.
  qrCodeValuePieceSize = QR_CODE_PIECE_SIZES[DEFAULT_QR_CODE_PIECE_SIZE_INDEX];
  qrCodeValuePieces: string[] = [];
  qrCodeValueIndex: number = 0;

  constructor(
    private readonly matchListRequestor: MatchListRequestor,
    private readonly actionsSubmitter: ActionsSubmitter
  ) {}

  ngOnInit() {
    this.actionHelper = new ActionHelper(
      (actionType: ActionType, action: ConcreteAction) => {
        this.addAction(actionType, action);
      }
    );

    // When the user navigated from the match list, we can skip the team
    // selection. I.e. we trust that the user clicked the correct button.
    this.section = this.skipTeamSelection ? 'Init' : 'Team Selection';
    this.fetchMatchList();
  }

  goToNextTeam() {
    this.ngOnInit();
    this.teamNumber = this.nextTeamNumber;
    this.nextTeamNumber = '';
  }

  async fetchMatchList() {
    this.progressMessage = 'Fetching match list. Please be patient.';
    this.errorMessage = '';

    try {
      this.matchList = await this.matchListRequestor.fetchMatchList();
      this.progressMessage = 'Successfully fetched match list.';
    } catch (e) {
      this.errorMessage = e;
      this.progressMessage = '';
    }
  }

  // This gets called when the user changes something on the Init screen.
  // It makes sure that the user can't click "Next" until the information is
  // valid, or this is for pre-scouting or practice matches.
  updateTeamSelectionValidity(): void {
    this.teamSelectionIsValid =
      this.compType != 'Regular' || this.matchIsInMatchList();
  }

  matchIsInMatchList(): boolean {
    // If the user deletes the content of the teamNumber field, the value here
    // is undefined. Guard against that.
    if (this.teamNumber == null) {
      return false;
    }

    for (const match of this.matchList) {
      if (
        this.matchNumber == match.matchNumber() &&
        this.setNumber == match.setNumber() &&
        this.compLevel == match.compLevel() &&
        (this.teamNumber === match.r1() ||
          this.teamNumber === match.r2() ||
          this.teamNumber === match.r3() ||
          this.teamNumber === match.b1() ||
          this.teamNumber === match.b2() ||
          this.teamNumber === match.b3())
      ) {
        return true;
      }
    }
    return false;
  }

  addPenalty(): void {
    this.penalties += 1;
  }

  removePenalty(): void {
    if (this.penalties > 0) {
      this.penalties -= 1;
    }
  }

  addPenalties(): void {
    this.actionHelper.addPenaltyAction({penalties: this.penalties});
  }

  addAction(actionType: ActionType, action: ConcreteAction): void {
    let timestamp: number = 0;

    if (actionType == ActionType.StartMatchAction) {
      // Unix nanosecond timestamp.
      this.matchStartTimestamp = Date.now() * 1e6;
    } else {
      // Unix nanosecond timestamp relative to match start.
      timestamp = Date.now() * 1e6 - this.matchStartTimestamp;
    }

    if (actionType == ActionType.EndMatchAction) {
      // endMatchAction occurs at the same time as penaltyAction so add to its
      // timestamp to make it unique.
      timestamp += 1;
    }

    if (actionType == ActionType.MobilityAction) {
      this.mobilityCompleted = true;
    }

    this.actionList.push(new ActionT(BigInt(timestamp), actionType, action));
  }

  undoLastAction() {
    if (this.actionList.length > 0) {
      let lastAction = this.actionList.pop();
      switch (lastAction?.actionTakenType) {
        case ActionType.EndAutoPhaseAction:
          this.autoPhase = true;
          this.section = 'Pickup';
          break;
        case ActionType.NoShowAction:
          this.autoPhase = true;
          this.section = 'Init';
          break;
        case ActionType.PickupNoteAction:
          this.section = 'Pickup';
          break;
        case ActionType.EndTeleopPhaseAction:
          this.section = 'Pickup';
          break;
        case ActionType.PlaceNoteAction:
          this.section = 'Place';
          break;
        case ActionType.EndMatchAction:
          this.section = 'Endgame';
        case ActionType.MobilityAction:
          this.mobilityCompleted = false;
          break;
        case ActionType.StartMatchAction:
          this.section = 'Init';
          break;
        case ActionType.RobotDeathAction:
          // TODO(FILIP): Return user to the screen they
          // clicked dead robot on. Pickup is fine for now but
          // might cause confusion.
          this.section = 'Pickup';
          break;
        default:
          break;
      }
    }
  }

  stringifyScoreType(scoreType: ScoreType): String {
    return ScoreType[scoreType];
  }

  stringifyStageType(stageType: StageType): String {
    return StageType[stageType];
  }

  changeSectionTo(target: Section) {
    // Clear the messages since they won't be relevant in the next section.
    this.errorMessage = '';
    this.progressMessage = '';

    // For the QR code screen, we need to make the value to encode available.
    if (target == 'QR Code') {
      this.updateQrCodeValuePieceSize();
    }

    this.section = target;
  }

  private scrollToTop() {
    this.header.nativeElement.scrollIntoView();
  }

  createActionsBuffer() {
    const builder = new Builder();
    const actionOffsets: number[] = [];

    for (const action of this.actionList) {
      if (STATE_ACTIONS.includes(action.actionTakenType)) {
        // Actions only used for undo purposes are not submitted.
        continue;
      }
      actionOffsets.push(action.pack(builder));
    }
    const teamNumberFb = builder.createString(this.teamNumber);
    const compLevelFb = builder.createString(this.compLevel);
    const compTypeFb = builder.createString(this.compType);

    const actionsVector = Submit2024Actions.createActionsListVector(
      builder,
      actionOffsets
    );
    Submit2024Actions.startSubmit2024Actions(builder);
    Submit2024Actions.addTeamNumber(builder, teamNumberFb);
    Submit2024Actions.addMatchNumber(builder, this.matchNumber);
    Submit2024Actions.addSetNumber(builder, this.setNumber);
    Submit2024Actions.addCompLevel(builder, compLevelFb);
    Submit2024Actions.addActionsList(builder, actionsVector);
    Submit2024Actions.addCompType(builder, compTypeFb);
    builder.finish(Submit2024Actions.endSubmit2024Actions(builder));

    return builder.asUint8Array();
  }

  // Same as createActionsBuffer, but encoded as Base64. It's also split into
  // a number of pieces so that each piece is roughly limited to
  // `qrCodeValuePieceSize` bytes.
  createBase64ActionsBuffers(): string[] {
    const originalBuffer = this.createActionsBuffer();
    const deflatedData = pako.deflate(originalBuffer, {level: 9});

    const pieceSize = this.qrCodeValuePieceSize;
    const fullValue = btoa(String.fromCharCode(...deflatedData));
    const numPieces = Math.ceil(fullValue.length / pieceSize);

    let splitData: string[] = [];
    for (let i = 0; i < numPieces; i++) {
      const splitPiece = fullValue.slice(i * pieceSize, (i + 1) * pieceSize);
      splitData.push(`${i}_${numPieces}_${pieceSize}_${splitPiece}`);
    }
    return splitData;
  }

  setQrCodeValueIndex(index: number) {
    this.qrCodeValueIndex = Math.max(
      0,
      Math.min(index, this.qrCodeValuePieces.length - 1)
    );
  }

  updateQrCodeValuePieceSize() {
    this.qrCodeValuePieces = this.createBase64ActionsBuffers();
    this.qrCodeValueIndex = 0;
  }

  async submit2024Actions() {
    const res = await this.actionsSubmitter.submit(this.createActionsBuffer());

    if (res.ok) {
      // We successfully submitted the data. Report success.
      this.section = 'Success';
      this.actionList = [];

      // Keep track of the position of the last robot, use to figure out what
      // the next robot in the same position is.
      let lastTeamPos = '0';
      for (const match of this.matchList) {
        if (
          this.matchNumber === match.matchNumber() &&
          this.setNumber === match.setNumber() &&
          this.compLevel === match.compLevel()
        ) {
          this.teamNumber = this.teamNumber;
          if (this.teamNumber == match.r1()) {
            lastTeamPos = 'r1';
          } else if (this.teamNumber == match.r2()) {
            lastTeamPos = 'r2';
          } else if (this.teamNumber == match.r3()) {
            lastTeamPos = 'r3';
          } else if (this.teamNumber == match.b1()) {
            lastTeamPos = 'b1';
          } else if (this.teamNumber == match.b2()) {
            lastTeamPos = 'b2';
          } else if (this.teamNumber == match.b3()) {
            lastTeamPos = 'b3';
          } else {
            console.log('Position of scouted team not found.');
          }
          break;
        }
      }
      if (lastTeamPos != '0') {
        this.matchNumber += 1;
        for (const match of this.matchList) {
          if (
            this.matchNumber == match.matchNumber() &&
            this.setNumber == match.setNumber() &&
            this.compLevel == match.compLevel()
          ) {
            if (lastTeamPos == 'r1') {
              this.nextTeamNumber = match.r1();
            } else if (lastTeamPos == 'r2') {
              this.nextTeamNumber = match.r2();
            } else if (lastTeamPos == 'r3') {
              this.nextTeamNumber = match.r3();
            } else if (lastTeamPos == 'b1') {
              this.nextTeamNumber = match.b1();
            } else if (lastTeamPos == 'b2') {
              this.nextTeamNumber = match.b2();
            } else if (lastTeamPos == 'b3') {
              this.nextTeamNumber = match.b3();
            } else {
              console.log('Position of last team not found.');
            }
            break;
          }
        }
      } else {
        console.log('Last team position not found.');
      }
      this.matchList = [];
      this.progressMessage = '';
      this.errorMessage = '';
      this.autoPhase = true;
      this.actionList = [];
      this.mobilityCompleted = false;
      this.compType = 'Regular';
      this.matchStartTimestamp = 0;
      this.selectedValue = 0;
    } else {
      const resBuffer = await res.arrayBuffer();
      const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
      const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);

      const errorMessage = parsedResponse.errorMessage();
      this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
    }
  }
}
