// Copyright (C) 2023 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 m from 'mithril';
import {
  type QueryResponse,
  runQueryForQueryTable,
} from '../../components/query_table/queries';
import type {Trace} from '../../public/trace';
import type {Tab} from '../../public/tab';
import {DetailsShell} from '../../widgets/details_shell';
import {type ResultsData, ResultsTable} from './results_table';

interface QueryResultTabConfig {
  readonly query: string;
  readonly title: string;
}

export class QueryResultsTab implements Tab {
  private queryResponse?: QueryResponse;

  constructor(
    private readonly trace: Trace,
    private readonly args: QueryResultTabConfig,
  ) {
    // Run the query and load data when the tab is created
    this.loadData();
  }

  private async loadData() {
    const result = await runQueryForQueryTable(
      this.args.query,
      this.trace.engine,
    );
    this.queryResponse = result;
  }

  getTitle(): string {
    const suffix = this.queryResponse
      ? ` (${this.queryResponse.rows.length})`
      : '';
    return `${this.args.title}${suffix}`;
  }

  render(): m.Children {
    const resp = this.queryResponse;

    return m(
      DetailsShell,
      {
        title: this.args.title,
        description: resp ? this.args.query : 'Loading...',
      },
      resp && this.renderResponse(resp),
    );
  }

  private renderResponse(resp: QueryResponse): m.Children {
    const data: ResultsData = resp.error
      ? {kind: 'error', errorMessage: resp.error}
      : {
          kind: 'success',
          columns: resp.columns,
          rows: resp.rows,
          rowCount: resp.totalRowCount,
          queryTimeMs: resp.durationMs,
          query: this.args.query,
          lastStatementSql: resp.lastStatementSql,
          statementCount: resp.statementCount,
          statementWithOutputCount: resp.statementWithOutputCount,
        };

    return m(ResultsTable, {
      data,
      fillHeight: true,
      trace: this.trace,
      onIdClick: (sqlTable, id, doubleClick) => {
        this.trace.selection.selectSqlEvent(sqlTable, id, {
          switchToCurrentSelectionTab: doubleClick,
          scrollToSelection: true,
        });
      },
    });
  }

  isLoading() {
    return this.queryResponse === undefined;
  }
}
