import { WorkspaceListQueryInput } from '@/operations/queries/workspace-list';
import { databaseManager } from '@/main/data/database-manager';
import { Workspace, WorkspaceRole } from '@/types/workspaces';
import { SelectWorkspace } from '@/main/data/app/schema';
import {
  MutationChange,
  ChangeCheckResult,
  QueryHandler,
  QueryResult,
} from '@/main/types';
import { isEqual } from 'lodash-es';

export class WorkspaceListQueryHandler
  implements QueryHandler<WorkspaceListQueryInput>
{
  public async handleQuery(
    _: WorkspaceListQueryInput
  ): Promise<QueryResult<WorkspaceListQueryInput>> {
    const rows = await this.fetchWorkspaces();

    return {
      output: this.buildWorkspaces(rows),
      state: {
        rows,
      },
    };
  }

  public async checkForChanges(
    changes: MutationChange[],
    _: WorkspaceListQueryInput,
    state: Record<string, any>
  ): Promise<ChangeCheckResult<WorkspaceListQueryInput>> {
    if (
      !changes.some(
        (change) => change.type === 'app' && change.table === 'workspaces'
      )
    ) {
      return {
        hasChanges: false,
      };
    }

    const rows = await this.fetchWorkspaces();
    if (isEqual(rows, state.rows)) {
      return {
        hasChanges: false,
      };
    }

    return {
      hasChanges: true,
      result: {
        output: this.buildWorkspaces(rows),
        state: {
          rows,
        },
      },
    };
  }

  private fetchWorkspaces(): Promise<SelectWorkspace[]> {
    return databaseManager.appDatabase
      .selectFrom('workspaces')
      .selectAll()
      .where(
        'account_id',
        'in',
        databaseManager.appDatabase
          .selectFrom('accounts')
          .where('status', '=', 'active')
          .select('id')
      )
      .execute();
  }

  private buildWorkspaces(rows: SelectWorkspace[]): Workspace[] {
    return rows.map((row) => {
      return {
        id: row.workspace_id,
        name: row.name,
        description: row.description,
        avatar: row.avatar,
        versionId: row.version_id,
        accountId: row.account_id,
        role: row.role as WorkspaceRole,
        userId: row.user_id,
      };
    });
  }
}
