import { AssetSelectorQueryFieldBase } from '../AssetSelectorQueryFieldBase';
import {
  AssetPropWhereOp,
  AssetPropWhereOpKind,
  AssetPropWhereValue,
} from '../PropsWhere';
import { AssetSelectorQueryBuilding } from '../AssetSelectorQuery';
import {
  AssetScope,
  AssetScopeToId,
  GAME_INFO_ASSET_ID,
  SYSTEM_PROJECT_ID,
} from '../../../constants';
import { AssetRights } from '../Rights';
import { escapeLiteral } from 'pg';
import { AccessTag } from '../../../utils/project-access';
import { joinAssetCompsForAssetSelectorQueryFieldAssetComps } from './AssetSelectorQueryFieldAssetComps';

export class AssetSelectorQueryFieldRights extends AssetSelectorQueryFieldBase {
  constructor() {
    super('rights');
  }

  requestProp(qb: AssetSelectorQueryBuilding): string {
    if (qb.context.accessTags.has(AccessTag.ROOT)) {
      return `${+AssetRights.FULL_ACCESS}`;
    }
    const conditions = [
      `WHEN a.project_id = ${+SYSTEM_PROJECT_ID} THEN ${+AssetRights.READ_ONLY}`,
    ];
    if (qb.context.userRole) {
      if (!qb.joinedTableMarks.has('assetRights')) {
        qb.query.leftJoin(
          'asset_user_rights',
          'aur',
          `aur.project_id = a.project_id AND aur.asset_id = a.id AND aur.user_id = ${+qb
            .context.userId}`,
        );
        qb.query.leftJoin(
          'asset_rights',
          'ar',
          `ar.project_id = a.project_id AND ar.asset_id = a.id AND ar.user_role_num = ${+qb
            .context.userRole.num}`,
        );
        qb.query.leftJoin(
          'workspace_rights',
          'ar_wr',
          `ar_wr.project_id = a.project_id AND ar_wr.workspace_id = a.workspace_id AND ar_wr.user_role_num = ${+qb
            .context.userRole.num}`,
        );
        qb.query.leftJoin(
          'scope_rights',
          'ar_sr',
          `ar_sr.scope_id = a.scope_id AND ar_sr.user_role_num = ${+qb.context
            .userRole.num}`,
        );
        qb.joinedTableMarks.set('assetRights', 'ar');
      }

      conditions.push(
        `ELSE COALESCE(aur.rights, ar.rights, ar_wr.rights, ar_sr.rights, ${+qb
          .context.userRole.defaultAssetRights})`,
      );
    } else {
      if (qb.context.projectParams.isPublicAbout) {
        joinAssetCompsForAssetSelectorQueryFieldAssetComps(qb);
        const escaped = escapeLiteral(GAME_INFO_ASSET_ID);
        conditions.push(
          `WHEN ac.type_ids && '{${escaped.substring(
            1,
            escaped.length - 1,
          )}}' THEN ${+AssetRights.READ_ONLY}`,
        );
      }
      if (qb.context.projectParams.isPublicGdd) {
        conditions.push(
          `WHEN a.scope_id = ${AssetScopeToId.get(
            AssetScope.DEFAULT,
          )} THEN ${+AssetRights.READ_ONLY}`,
        );
      }
      if (
        qb.context.projectParams.isPublicTasks &&
        qb.context.accessTags.has(AccessTag.TASKS)
      ) {
        conditions.push(
          `WHEN a.scope_id = ${AssetScopeToId.get(
            AssetScope.TASKS,
          )} THEN ${+AssetRights.READ_ONLY}`,
        );
      }
      conditions.push(`ELSE ${+AssetRights.NO}`);
    }
    return `(CASE ${conditions.join('\n')} END)`;
  }

  protected prepareFilterValue(val: AssetPropWhereValue): any {
    if (val === null) return null;
    if (typeof val === 'number') return Math.round(val);
    return parseInt(val.toString());
  }
}
