import { AfterViewInit, Component, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
import { Centers } from 'src/app/lib/filler/common/interfaces';
import { EditorDirective } from 'src/app/lib/filler/editor.directive';
import CheckEditLayer from 'src/app/lib/filler/check-edit/check-edit-layer';
import { ToolConfig, ToolConfigs } from 'src/app/lib/filler/tool-config';
import { Location } from '@angular/common';
import Utils from 'src/app/lib/filler/common/utils';
import FillArea from 'src/app/lib/filler/common/fillarea';
import Rect from 'src/app/lib/filler/core/rect';
import { PreCheckResult } from './interfaces';

@Component({
  selector: 'app-pre-checker',
  template: `
<canvas appEditor></canvas>
<div class="toolbar toolbar-top" *ngIf="editorRef">
  <div class="btn-group">
    <button class="btn btn-xs btn-default" (click)="return()" i18n>返回</button>
    <button class="btn btn-xs btn-default" (click)="onOpenUpload()" i18n>上传文件</button>

    <!-- <button *ngFor="let tool of tools" class="btn btn-default" [ngClass]="{'btn-primary': tool.active}" type="button"
      (click)="editorRef.editor.setToolByKey(tool.key)">
      <i class="pr-1" [ngClass]="tool.icon"></i>
      <span>{{tool.name || tool.key}} </span>
    </button> -->

    <button *ngFor="let tool of tools" class="btn btn-default" placement="bottom" ngbTooltip="{{tool.tooltip || tool.shortcut}}"
      [ngClass]="{'btn-primary': tool.active, '' : !tool.active}" type="button"
      (click)="editorRef.editor.setToolByKey(tool.key); updateTools()">
      <i class="pr-1" [ngClass]="tool.icon"></i>
      <span>{{tool.name || tool.key}} </span>
    </button>


    <button *ngIf="checkEditLayer" class="btn btn-default" [ngClass]="{ 'btn-primary': checkEditLayer?.showMark == true }"
      type="button" (click)="checkEditLayer.toggleMark()">
      <i class="fas fa-check"></i>
      <span i18n>标记</span>
    </button>

    <!-- <button *ngIf="checkEditLayer" class="btn btn-default" [ngClass]="{ 'btn-primary': checkEditLayer?.lineMark == true }" 
      type="button" (click)="checkEditLayer?.toggleLineMark()">
      <i class="fas fa-check"></i>
      <span>线条闭合检测</span>
    </button> -->

    <button *ngIf="checkEditLayer" class="btn btn-default" [ngClass]="{ 'btn-primary': checkEditLayer?.showMap == true }"
      type="button" (click)="checkEditLayer.toggleMap()">
      <i class="fas fa-table"></i>
      <span i18n>显示map</span>
    </button>

    <button *ngIf="checkEditLayer" class="btn btn-default" [ngClass]="{ 'btn-primary': checkEditLayer?.showPage!= true }"
      type="button" (click)="checkEditLayer.togglePage()">
      <i class="fas fa-eye-slash"></i>
      <span i18n>隐藏线稿</span>
    </button>

    <button *ngIf="checkEditLayer && checkEditLayer.floodImgs.length > 0" placement="bottom" ngbTooltip="0" class="btn " 
      [ngClass]="{ 'btn-primary': checkEditLayer.showFloodIdx < 100 }" type="button" 
      (click)="checkEditLayer?.toggleParse()">
      <i class="far fa-analytics"></i>
      <span i18n>分析模式</span>
    </button>

    <div *ngIf="checkEditLayer && checkEditLayer.showFloodIdx < 100" class="btn-group ">
      <button type="button" class="btn  dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true"
        aria-expanded="false" i18n>分析过程</button>
      <div class="dropdown-menu">
        <ng-container *ngFor="let img of checkEditLayer.floodImgs; let i=index">
          <a class="dropdown-item" placement="right" [ngbTooltip]="(i+1).toString()"
          [ngStyle]="{'background-color' : checkEditLayer.showFloodIdx == i ? 'orange' : ''}"
          (click)="checkEditLayer.showFloodIdx = i"
          href="javascript:void(0)">
          <span i18n>第{{i+1}}步</span>
        </a>
        </ng-container>
      </div>
    </div>

    <button class="btn btn-xs btn-default" (click)="download()" i18n>导出</button>
  </div>

</div>


<div class="toolbar toolbar-bottom " *ngIf="editorRef">
  <div style="pointer-events:none;">

    <div class="btn-group  shadow-sm" >

      <button placement="top" ngbTooltip="f" class="btn  " (click)="utils.toggleFullscreen()">
        <i *ngIf="!utils.isFullscreen()" class="fal fa-expand-arrows-alt"></i>
        <i *ngIf="utils.isFullscreen()" class="fal fa-compress-arrows-alt"></i>
        {utils.isFullscreen() ? 'true' : 'false', select,  true {退出全屏} false {全屏}}
      </button>

      <button placement="top" ngbTooltip="d" class="btn " type="button" (click)="editorRef?.editor?.bestFit()">
        <i class="ti-layout-slider pdd-right-5"></i>
        <span i18n>居中</span>
      </button>
      <label class="btn  scale">{{editorRef?.editor?.getScale().x | percent}}</label>

      <button placement="top" ngbTooltip="r" class="btn " type="button" (click)="editorRef?.editor?.reset100()">
        <i class="fal fa-expand-arrows pr-1"></i>
        <span>1:1</span>
      </button>

    </div>
  </div>
</div>

<div class="toolbar-left" *ngIf="editorRef && checkEditLayer">
  <div class="p-1" [ngSwitch]="checkEditLayer.result">
    <ng-container i18n>检查结果</ng-container>：
    <span *ngSwitchCase="0" class="text-info">
      <strong i18n>检测中...</strong>
    </span>
    <span *ngSwitchCase="1" class="text-success">
      <strong i18n>合格</strong>
    </span>
    <span *ngSwitchCase="2" class="text-danger">
      <strong i18n>不合格</strong>
    </span>
  </div>
  <div class="p-1">
    <ng-container i18n>分辨率</ng-container>: {{page.width}}x{{page.height}}
  </div>
  <div class="p-1">
    <ng-container i18n>总区块</ng-container>: {{checkEditLayer?.sortedAreaList.length}}
  </div>
  <div class="p-1 ">
    <ng-container i18n>小区块</ng-container>: <strong>{{checkEditLayer?.smallAreas.length}}</strong> (<ng-container i18n>最多允许</ng-container>:{{N}})
  </div>
  <div class="p-1" [ngClass]="{'text-danger': checkEditLayer.noCenterAreas.length > 0}">
    <ng-container i18n>无效小区块</ng-container>: {{checkEditLayer.noCenterAreas.length}}
  </div>
  <div class="p-1" [ngClass]="{'text-warning': (checkEditLayer.smallAreas.length - checkEditLayer.noCenterAreas.length) > 0}">
    <ng-container i18n>有效小区块</ng-container>: {{checkEditLayer.smallAreas.length - checkEditLayer.noCenterAreas.length}}
  </div>
  <div class="p-1">
    <ng-container i18n>小区块标准</ng-container>：R <= {{R}}
  </div>
  <div class="p-1 text-primary">
    <ng-container i18n>疑似未闭合线条</ng-container>: {{checkEditLayer.noCloseLines.length}}
  </div>
</div>


<div class="toolbar-right" *ngIf="editorRef">
  <div class="area-list shadow-sm">
    <div class="area-list-header">
      <div class="p-2">
        <ng-container i18n>小区块数</ng-container>：{{checkEditLayer?.smallAreas.length}}
      </div>
      <div>
        <button class="btn  " (click)="showAreaList=!showAreaList; ">
          <i *ngIf="showAreaList" class="fa fa-angle-up"></i>
          <i *ngIf="!showAreaList" class="fa fa-angle-down"></i>
        </button>
      </div>
    </div>
    <ng-container *ngIf="showAreaList">
      <div class="area-item" *ngFor="let area of checkEditLayer?.smallAreas" [style.background]="area.colorRgba"
        (click)="focusToArea(area)">
        {{area.count}}
      </div>
    </ng-container>
  </div>
</div>

<div *ngIf="isUpload" class="upload-wraper">
  <app-prechecker-upload (data)="onUpload($event)"></app-prechecker-upload>
</div>


  `,
  styleUrls: ['./play.component.css']
})



export class PrecheckerComponent implements OnInit, AfterViewInit, OnDestroy {
  @HostListener('window:keydown', ['$event'])
  keyEvent(event: KeyboardEvent) {

    if (this.isUpload) return;
    let key = event.key.toLocaleLowerCase();
    let isCtrl = event.ctrlKey;
    let isMeta = event.metaKey;
    let isCtrlOrMeta = isCtrl || isMeta;

    console.log(key, isCtrl, isMeta);


    if ('f' == key) {
      Utils.toggleFullscreen(); //全屏
    } else if ('d' == key) {
      this.editorRef.editor.bestFit(); //居中
    } else if (' ' == key) { //space
      this.editorRef.editor.setToolByKey('pan'); //移动工具
      this.updateTools();
    } else if ('q' == key) { //隐藏线稿 
      this.checkEditLayer.togglePage();
      event.preventDefault();
    } else if ('m' == key) { //生成floodfill各个阶段的结果图，方便查看效果和调试（供开发使用）
      this.checkEditLayer.makeFloodFill();
    } else if ('r' == key) {
      this.editorRef.editor.reset100(); //100%
    } else if ('0' == key) {
      this.checkEditLayer.toggleParse();
    } else if ('1' == key) {
      this.checkEditLayer.showFloodIdx = 0;
    } else if ('2' == key) {
      this.checkEditLayer.showFloodIdx = 1;
    } else if ('3' == key) {
      this.checkEditLayer.showFloodIdx = 2;
    } else if ('4' == key) {
      this.checkEditLayer.showFloodIdx = 3;
    } else if ('5' == key) {
      this.checkEditLayer.showFloodIdx = 4;
    } else if ('6' == key) {
      this.checkEditLayer.showFloodIdx = 5;
    } else if ('7' == key) {
      this.checkEditLayer.showFloodIdx = 6;
    } else if ('8' == key) {
      this.checkEditLayer.showFloodIdx = 7;
    } else {
    }

  }



  @ViewChild(EditorDirective)
  editorRef: EditorDirective;

  checkEditLayer: CheckEditLayer;

  @Input() raw: HTMLImageElement;

  @Input() page: HTMLImageElement;

  @Input() map: HTMLImageElement;

  @Input() centers: Centers;

  @Input() R: number = 2; //小区块半径阈值
  @Input() N: number = 30; //小于Rmin的区块数阈值

  @Output() onReturn = new EventEmitter();

  showAreaList: boolean = false;

  work: Blob;

  isUpload: boolean = false;

  constructor(
    public location: Location,) { 
    console.log();
  }

  ngOnInit(): void {
  }

  async ngAfterViewInit() {
    await this.editorRef.editor.ready;

    if (!this.page) {
      this.isUpload = true;
      return;
    } 
    this.checkEditLayer = new CheckEditLayer(this.raw, this.page, this.map, this.centers, this.R, this.N);
    this.editorRef.editor.setBackgroundLayer(this.checkEditLayer, true);
  }

  ngOnDestroy(): void {
    this.checkEditLayer.destroy();
  }

  get tools(): any[] {
    return this.editorRef?.editor.getToolsStatus().map(ts => {
      let config = ToolConfigs[ts.key];
      if (config) Object.assign(ts, config);
      return ts;
    });
  }

  get utils() { return Utils }

  toolShotcuts: { [key: string]: ToolConfig };

  updateTools(): void {
    console.log(this.tools);
    this.toolShotcuts = this.tools.reduce((r, c: ToolConfig) => {
      if (c.shortcut) { r[c.shortcut] = c; }
      return r;
    }, {});
  }

  /**
   * 编辑器聚焦到填色区域
   * @param area 
   */
  focusToArea(area: FillArea) {
    let rect = new Rect(area.left, area.top, area.right, area.bottom);
    this.editorRef.editor.focusToRect(rect);
    this.checkEditLayer.blinkByAreas([area]);
  }

  //导出图片 
  async download() {
    if (!this.work) {
      this.work = await this.checkEditLayer.getWorkBlob();
    }
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(this.work);
    a.href = url;
    a.download = 'page.png';
    a.click();
  }

  onUpload(result: PreCheckResult) {
    this.raw = result.raw;
    this.page = result.page;
    this.map = result.map;
    this.centers = result.centers;
    this.R = result.R;
    this.N = result.N;
    this.checkEditLayer = new CheckEditLayer(this.raw, this.page, this.map, this.centers, this.R, this.N);
    this.editorRef.editor.setBackgroundLayer(this.checkEditLayer, true);

    //关闭上传界面
    this.isUpload = false;
  }

  return() {
    this.onReturn.emit();
  }

  
  onOpenUpload() {
    this.isUpload = true;
  }


  

}