import {
  Provide,
  Inject,
  Controller,
  Get,
  Post,
  Query,
  Body,
} from '@midwayjs/decorator';
import { DataService } from '../../service/data.service';
import { tileService } from '../../service/3dtile.service';
import { mbTileService } from '../../service/mbtile.service';
import { DataMongoService } from '../../service/data-mongo.service';
import { Context } from '@midwayjs/koa';
import * as geojson from 'geojson';
import { ApiOperation } from '@midwayjs/swagger';

@Provide()
@Controller('/')
export class BaseJtCommController {
  @Inject()
  dataService: DataService;
  @Inject()
  dataMongoService: DataMongoService;
  @Inject()
  tileService: tileService;
  @Inject()
  mbTileService: mbTileService;
  @Inject()
  ctx: Context;

  @Get('/')
  public async welcome() {
    await this.ctx.render('welcome', {
      text: '技术改变未来，欢迎您！！！',
    });
  }
  /**
   * 接口界面
   */
  @Get('/test')
  public async test() {
    await this.ctx.render('testview');
  }

  /**
   * 基本查询
   * @param tableName 表名
   * @param sqlWhere 查询条件
   * @param orderByField 排序字段
   * @returns 查询内容
   */
  @ApiOperation({ summary: '基础查询' })
  @Get('/getTableList')
  async home(
    @Query('tableName') tableName: string,
    @Query('sqlWhere') sqlWhere: string,
    @Query('orderByField') orderByField: string
  ) {
    try {
      const key = '0l23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      tableName = this.formCode(tableName, key);
      const tableField = await this.dataService.getField(tableName);
      let fields = '';
      let result = '';
      let message = '';
      if (tableField.length > 0) {
        fields = JSON.parse(JSON.stringify(tableField));
        message = 'OK';
        result = await this.dataService.getList(
          tableName,
          this.formCode(sqlWhere, key),
          this.formCode(orderByField, key)
        );
        if (result.length > 0) {
          return {
            success: true,
            message: message,
            table: fields,
            data: result,
          };
        } else {
          return {
            success: false,
            message: '无数据获取',
            table: fields,
            data: result,
          };
        }
      } else {
        return {
          success: false,
          message: '查询失败,失败原因是没有对' + tableName + '进行配置',
          table: fields,
          data: result,
        };
      }
    } catch (error) {
      return { success: false, message: error };
    }
  }

  formCode(str, key) {
    //定义密钥，36个字母和数字
    let l = key.length; //获取密钥的长度
    let b,
      bl,
      b2,
      b3,
      d = 0,
      s; //定义临时变量
    s = new Array(Math.floor(str.length / 3)); //计算加密字符串包含的字符数，并定义数组
    b = s.length; //获取数组的长度
    for (let i = 0; i < b; i++) {
      //以数组的长度循环次数，遍历加密字符串
      bl = key.indexOf(str.charAt(d)); //截取周期内第一个字符串，计算在密钥中的下标值
      d++;
      b2 = key.indexOf(str.charAt(d)); //截取周期内第二个字符串，计算在密钥中的下标值
      d++;
      b3 = key.indexOf(str.charAt(d)); //截取周期内第三个字符串，计算在密钥中的下标值
      d++;
      s[i] = bl * l * l + b2 * l + b3; //利用下标值，反推被加密字符的Unicode编码值
    }
    b = eval('String.fromCharCode(' + s.join(',') + ')'); //用fromCharCode()算出字符串
    return b; //返回被解密的字符串
  }

  /**
   * 空间查询
   * @param tableName 表名
   * @param sqlWhere 查询条件
   * @param orderByField 排序字段
   * @returns 查询内容
   */
  @ApiOperation({ summary: '空间查询' })
  @Get('/getGeoJson')
  async getGeoJson(
    @Query('tableName') tableName: string,
    @Query('sqlWhere') sqlWhere: string,
    @Query('orderByField') orderByField: string
  ) {
    try {
      const key = '0l23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      tableName = this.formCode(tableName, key);
      const tableField = await this.dataService.getField(tableName);

      let fields = '';
      let geoResult = '';
      let message = '';
      if (tableField.length > 0) {
        fields = JSON.parse(JSON.stringify(tableField));
        message = 'OK';
        const result = await this.dataService.getGeoList(
          tableName,
          this.formCode(sqlWhere, key),
          this.formCode(orderByField, key)
        );
        geoResult = geojson.parse(result, { GeoJSON: 'geom' });
      } else {
        message = '查询失败,失败原因是没有对' + tableName + '进行配置';
      }

      return {
        success: true,
        message: message,
        table: fields,
        data: geoResult,
      };
    } catch (error) {
      return { success: false, message: error };
    }
  }

  /**
   * 新增或修改
   * @param tableName 表名
   * @param keyValue 主键值
   * @param formData 新增或修改内容
   * @returns 更新信息
   */
  @ApiOperation({ summary: '新增或修改' })
  @Post('/postSubmit')
  async formSubmit(
    @Body('tableName') tableName: string,
    @Body('keyValue') keyValue: string,
    @Body('formData') formData: object
  ) {
    try {
      const key = '0l23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      tableName = this.formCode(tableName, key);
      // formData = this.formCode(formData, key);
      const result = await this.dataService.addOrUpdateComm(
        tableName,
        keyValue,
        formData
        // files[0]
      );

      return {
        success: true,
        message: 'OK',
        rowCount: result,
      };
    } catch (error) {
      return { success: false, message: error };
    }
  }

  /**
   * 删除
   * @param tableName 表名
   * @param keyValue 主键值
   * @returns 更新信息
   */
  @ApiOperation({ summary: '删除' })
  @Get('/delete')
  async formDelete(
    @Query('tableName') tableName: string,
    @Query('keyValue') keyValue: string
  ) {
    try {
      const key = '0l23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      tableName = this.formCode(tableName, key);
      const result = await this.dataService.deleteComm(tableName, keyValue);

      return {
        success: true,
        message: 'OK',
        rowCount: result,
      };
    } catch (error) {
      return { success: false, message: error };
    }
  }

  /**
   * 缓冲区空间查询
   * @param tableName 表名
   * @param spatialType 空间类型
   * @param coordinate 坐标
   * @param buffer 缓冲区
   * @returns 空间信息
   */
  @ApiOperation({ summary: '缓冲区空间查询' })
  @Get('/getSpatialQuery')
  async spatialQuery(
    @Query('tableName') tableName: string,
    @Query('spatialType') spatialType: string,
    @Query('coordinate') coordinate: string,
    @Query('buffer') buffer: string,
    @Query('sqlWhere') sqlWhere: string
  ) {
    try {
      const key = '0l23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      tableName = this.formCode(tableName, key);
      sqlWhere = this.formCode(sqlWhere, key);
      const tableField = await this.dataService.getField(tableName);

      const fields = JSON.parse(JSON.stringify(tableField));

      const result = await this.dataService.getSpatialList(
        tableName,
        spatialType,
        coordinate,
        buffer,
        sqlWhere
      );

      const geoResult = geojson.parse(result, { GeoJSON: 'geom' });

      return {
        success: true,
        message: 'OK',
        table: fields,
        data: geoResult,
      };
    } catch (error) {
      return { success: false, message: error };
    }
  }
  /**
   * 3dTiles查询
   * @returns 查询内容
   */
  @ApiOperation({ summary: '3dTiles查询' })
  @Get('/get3dTiles/*')
  async get3dTiles() {
    try {
      this.ctx.set('Content-Type', 'text/html; charset=UTF-8');
      this.ctx.set('Vary', 'Accept-Encoding');
      const d3tileUrl = this.ctx.URL;
      const result = await this.tileService.get3dTiles(d3tileUrl);

      return result;
    } catch (error) {
      return error;
    }
  }
  /**
   * mbTiles查询
   * @returns 查询内容
   */
  @ApiOperation({ summary: 'mbTiles查询' })
  @Get('/getMbTiles/:tiles/:z/:x/:y.png')
  async getMbTiles() {
    try {
      this.ctx.set('Content-Type', 'image/png');
      // this.ctx.set('Vary', 'Accept-Encoding');
      const mbTileUrl = this.ctx.params;
      const result = await this.mbTileService.getMbTiles(
        mbTileUrl.tiles,
        mbTileUrl.z,
        mbTileUrl.x,
        mbTileUrl.y
      );

      return result;
    } catch (error) {
      return error;
    }
  }
  /**
   * 管线分段
   * @param tableName 表名
   * @param pipeLineName 管线名称
   * @param points 段数
   * @returns 空间信息
   */
  @ApiOperation({ summary: '管线分段' })
  @Post('/getLineInterpolatePoints')
  async lineInterpolatePoints(
    @Body('tableName') tableName: string,
    @Body('name') name: object,
    @Body('type') type: string,
    @Body('number') number: number
  ) {
    try {
      const key = '0l23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      tableName = this.formCode(tableName, key);
      const tableField = await this.dataService.getField(tableName);

      const fields = JSON.parse(JSON.stringify(tableField));

      const result = await this.dataService.getLineInterpolatePoints(
        tableName,
        name,
        type,
        number
      );

      const geoResult = geojson.parse(result, { GeoJSON: 'geom' });

      return {
        success: true,
        message: 'OK',
        table: fields,
        data: geoResult,
      };
    } catch (error) {
      return { success: false, message: error };
    }
  }
  /**
   * 管线两点间距离
   * @param tableName 表名
   * @param name 查询名
   * @param points 点坐标
   * @returns
   */
  @ApiOperation({ summary: '管线两点间距离' })
  @Post('/getLineDistance')
  async lineDistance(
    @Body('tableName') tableName: string,
    @Body('name') name: object,
    @Body('point_one') point_one: string,
    @Body('point_two') point_two: string
  ) {
    try {
      const key = '0l23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      tableName = this.formCode(tableName, key);
      const tableField = await this.dataService.getField(tableName);

      const fields = JSON.parse(JSON.stringify(tableField));

      const result = await this.dataService.getLineDistance(
        tableName,
        name,
        point_one,
        point_two
      );

      const geoResult = geojson.parse(result, { GeoJSON: 'geom' });

      return {
        success: true,
        message: 'OK',
        table: fields,
        data: geoResult,
      };
    } catch (error) {
      return { success: false, message: error };
    }
  }
}
