import {Component, OnInit} from '@angular/core';
import {Builder, ByteBuffer} from 'flatbuffers';
import {ErrorResponse} from '@org_frc971/scouting/webserver/requests/messages/error_response_generated';
import {
  Ranking,
  RequestAllDriverRankingsResponse,
} from '@org_frc971/scouting/webserver/requests/messages/request_all_driver_rankings_response_generated';
import {
  Stats2024,
  Request2024DataScoutingResponse,
} from '@org_frc971/scouting/webserver/requests/messages/request_2024_data_scouting_response_generated';

import {
  PitImage,
  RequestAllPitImagesResponse,
} from '@org_frc971/scouting/webserver/requests/messages/request_all_pit_images_response_generated';

import {
  Note,
  RequestAllNotesResponse,
} from '@org_frc971/scouting/webserver/requests/messages/request_all_notes_response_generated';
import {Delete2024DataScouting} from '@org_frc971/scouting/webserver/requests/messages/delete_2024_data_scouting_generated';
import {Delete2024DataScoutingResponse} from '@org_frc971/scouting/webserver/requests/messages/delete_2024_data_scouting_response_generated';

import {
  MatchListRequestor,
  ViewDataRequestor,
} from '@org_frc971/scouting/www/rpc';

type Source = 'Notes' | 'Stats2024' | 'PitImages' | 'DriverRanking';

//TODO(Filip): Deduplicate
const COMP_LEVEL_LABELS = {
  qm: 'Qualifications',
  ef: 'Eighth Finals',
  qf: 'Quarter Finals',
  sf: 'Semi Finals',
  f: 'Finals',
};

@Component({
  selector: 'app-view',
  templateUrl: './view.ng.html',
  styleUrls: ['../app/common.css', './view.component.css'],
})
export class ViewComponent {
  constructor(private readonly viewDataRequestor: ViewDataRequestor) {}

  // Make COMP_LEVEL_LABELS available in view.ng.html.
  readonly COMP_LEVEL_LABELS = COMP_LEVEL_LABELS;

  // Progress and error messages to display to
  // the user when fetching data.
  progressMessage: string = '';
  errorMessage: string = '';

  // The current data source being displayed.
  currentSource: Source = 'Notes';

  // Current sort (ascending/descending match numbers).
  // noteList is sorted based on team number until match
  // number is added for note scouting.
  ascendingSort = true;

  // Stores the corresponding data.
  noteList: Note[] = [];
  driverRankingList: Ranking[] = [];
  pitImageList: PitImage[][] = [];
  statList: Stats2024[] = [];

  // Fetch notes on initialization.
  ngOnInit() {
    this.fetchCurrentSource();
  }

  // Called when a user changes the sort direction.
  // Changes the data order between ascending/descending.
  sortData() {
    this.ascendingSort = !this.ascendingSort;
    if (!this.ascendingSort) {
      this.driverRankingList.sort((a, b) => b.matchNumber() - a.matchNumber());
      this.noteList.sort(function (a, b) {
        return b.team().localeCompare(a.team(), undefined, {numeric: true});
      });
      this.pitImageList.sort(function (a, b) {
        return b[0]
          .teamNumber()
          .localeCompare(a[0].teamNumber(), undefined, {numeric: true});
      });
      this.statList.sort((a, b) => b.matchNumber() - a.matchNumber());
    } else {
      this.driverRankingList.sort((a, b) => a.matchNumber() - b.matchNumber());
      this.noteList.sort(function (a, b) {
        return a.team().localeCompare(b.team(), undefined, {numeric: true});
      });
      this.pitImageList.sort(function (a, b) {
        return a[0]
          .teamNumber()
          .localeCompare(b[0].teamNumber(), undefined, {numeric: true});
      });
      this.statList.sort((a, b) => a.matchNumber() - b.matchNumber());
    }
  }

  // Called when a user selects a new data source
  // from the dropdown.
  switchDataSource(target: Source) {
    this.currentSource = target;
    this.progressMessage = '';
    this.errorMessage = '';
    this.noteList = [];
    this.driverRankingList = [];
    this.statList = [];
    this.pitImageList = [];
    this.fetchCurrentSource();
  }

  // Call the method to fetch data for the current source.
  fetchCurrentSource() {
    switch (this.currentSource) {
      case 'Notes': {
        this.fetchNotes();
      }

      case 'Stats2024': {
        this.fetchStats2024();
      }

      case 'PitImages': {
        this.fetchPitImages();
      }

      case 'DriverRanking': {
        this.fetchDriverRanking();
      }
    }
  }

  // TODO(Filip): Add delete functionality.
  // Gets called when a user clicks the delete icon (note scouting).
  async deleteNoteData() {
    const block_alerts = document.getElementById(
      'block_alerts'
    ) as HTMLInputElement;
    if (block_alerts.checked || window.confirm('Actually delete data?')) {
      this.errorMessage = 'Deleting data has not been implemented yet.';
      return;
    }
  }

  // TODO(Filip): Add delete functionality.
  // Gets called when a user clicks the delete icon (driver ranking).
  async deleteDriverRankingData() {
    const block_alerts = document.getElementById(
      'block_alerts'
    ) as HTMLInputElement;
    if (block_alerts.checked || window.confirm('Actually delete data?')) {
      this.errorMessage = 'Deleting data has not been implemented yet.';
      return;
    }
  }

  // Gets called when a user clicks the delete icon.
  async delete2024DataScouting(
    compLevel: string,
    matchNumber: number,
    setNumber: number,
    teamNumber: string
  ) {
    const block_alerts = document.getElementById(
      'block_alerts'
    ) as HTMLInputElement;
    if (block_alerts.checked || window.confirm('Actually delete data?')) {
      await this.requestDelete2024DataScouting(
        compLevel,
        matchNumber,
        setNumber,
        teamNumber
      );
      await this.fetchStats2024();
    }
  }

  async requestDelete2024DataScouting(
    compLevel: string,
    matchNumber: number,
    setNumber: number,
    teamNumber: string
  ) {
    this.progressMessage = 'Deleting data. Please be patient.';
    const builder = new Builder();
    const compLevelData = builder.createString(compLevel);
    const teamNumberData = builder.createString(teamNumber);

    builder.finish(
      Delete2024DataScouting.createDelete2024DataScouting(
        builder,
        compLevelData,
        matchNumber,
        setNumber,
        teamNumberData
      )
    );

    const buffer = builder.asUint8Array();
    const res = await fetch('/requests/delete/delete_2024_data_scouting', {
      method: 'POST',
      body: buffer,
    });

    if (!res.ok) {
      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}"`;
    }
  }

  // Fetch all driver ranking data and store in driverRankingList.
  async fetchDriverRanking() {
    this.progressMessage = 'Fetching driver ranking data. Please be patient.';
    this.errorMessage = '';

    try {
      this.driverRankingList =
        await this.viewDataRequestor.fetchDriverRankingList();
      this.progressMessage = 'Successfully fetched driver ranking data.';
    } catch (e) {
      this.errorMessage = e;
      this.progressMessage = '';
    }
  }

  // Fetch all pit image data and store in pitImageList.
  async fetchPitImages() {
    this.progressMessage = 'Fetching pit image list. Please be patient.';
    this.errorMessage = '';

    try {
      const initialPitImageList =
        await this.viewDataRequestor.fetchPitImagesList();
      let officialPitImageList = [];
      // Use iteration to make an array of arrays containing pit image data for individual teams.
      // Ex. [ [ {971PitImageData} , {971PitImage2Data} ], [ {432PitImageData} ] , [ {213PitImageData} ] ]
      for (let pitImage of initialPitImageList) {
        let found = false;
        for (let arr of officialPitImageList) {
          if (arr[0].teamNumber() == pitImage.teamNumber()) {
            arr.push(pitImage);
            found = true;
          }
        }
        if (!found) {
          officialPitImageList.push([pitImage]);
        }
      }
      // Sort the arrays based on image file names so their order is predictable.
      for (let arr of officialPitImageList) {
        arr.sort((a, b) => (a.imagePath() > b.imagePath() ? 1 : -1));
      }
      this.pitImageList = officialPitImageList;
      this.sortData();
      this.progressMessage = 'Successfully fetched pit image list.';
    } catch (e) {
      this.errorMessage = e;
      this.progressMessage = '';
    }
  }

  // Fetch all data scouting (stats) data and store in statList.
  async fetchStats2024() {
    this.progressMessage = 'Fetching stats list. Please be patient.';
    this.errorMessage = '';

    try {
      this.statList = await this.viewDataRequestor.fetchStats2024List();
      this.progressMessage = 'Successfully fetched stats list.';
    } catch (e) {
      this.errorMessage = e;
      this.progressMessage = '';
    }
  }

  // Fetch all notes data and store in noteList.
  async fetchNotes() {
    this.progressMessage = 'Fetching notes list. Please be patient.';
    this.errorMessage = '';

    try {
      this.noteList = await this.viewDataRequestor.fetchNoteList();
      this.progressMessage = 'Successfully fetched note list.';
    } catch (e) {
      this.errorMessage = e;
      this.progressMessage = '';
    }
  }

  // Parse all selected keywords for a note entry
  // into one string to be displayed in the table.
  parseKeywords(entry: Note) {
    let parsedKeywords = '';

    if (entry.goodDriving()) {
      parsedKeywords += 'Good Driving ';
    }
    if (entry.badDriving()) {
      parsedKeywords += 'Bad Driving ';
    }
    if (entry.noShow()) {
      parsedKeywords += 'No Show ';
    }
    if (entry.solidPlacing()) {
      parsedKeywords += 'Solid Placing ';
    }
    if (entry.sketchyPlacing()) {
      parsedKeywords += 'Sketchy Placing ';
    }
    if (entry.goodDefense()) {
      parsedKeywords += 'Good Defense ';
    }
    if (entry.badDefense()) {
      parsedKeywords += 'Bad Defense ';
    }
    if (entry.easilyDefended()) {
      parsedKeywords += 'Easily Defended';
    }

    return parsedKeywords;
  }
}
