import { Component, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
import { CollectionService } from './collection.service';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal';
import { HttpErrorResponse } from '@angular/common/http';
import { Location } from '@angular/common';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NzUploadFile } from 'ng-zorro-antd/upload';
import Utils from 'src/app/lib/filler/common/utils';
import { filter, firstValueFrom } from 'rxjs';
import { CollectionAddContentComponent } from './collection-add-content.component';
import { FormUtils } from 'src/app/lib/utils/form-utils';
import { CdkDragDrop, CdkDragEnter, moveItemInArray } from '@angular/cdk/drag-drop';

@Component({
  selector: 'app-collection-detail',
  template: `
<nz-spin [nzSpinning]="isLoading">

<nz-page-header [nzGhost]="false">
  <nz-page-header-title>[{{title}}]<span class="ms-1" i18n>收集详情</span></nz-page-header-title>
  <nz-page-header-extra>
    <button class="btn " *can="['create', 'any', 'art-collection']" (click)="onReturn()" i18n>返回</button>
    <nz-badge nzDot [nzShowDot]="form.dirty">
      <button class="btn" *can="['update', 'any', 'art-collection']" (click)="onSave()" [disabled]="!form.dirty" i18n>保存</button>
    </nz-badge>
    <button class="btn  btn-outline-danger" *can="['delete', 'any', 'art-collection']" cgOpButton 
        i18n-confirmContent confirmContent="确定要删除么？" [operation]="remove.bind(this)" (onSuccess)="onReturn()">
        <i class="fal fa-trash-alt"></i><ng-container i18n>删除</ng-container>
    </button>
  </nz-page-header-extra>
</nz-page-header>

<form id="form" [formGroup]="form" autocomplete="off" novalidate>

<div class="d-flex justify-content-start">
  <div>
    <div *ngIf="iconFile && !iconRatioGood()" class="text-danger" i18n>
      尺寸错误: 要求等宽高
    </div>
    <div *ngIf="iconFile && !iconSizeGood()" class="text-danger" i18n>
      图片大小超过限制（最大允许2M）
    </div>
    <div class="upload-box-icon" [ngClass]="{'bad': iconFile && (!iconSizeGood() || !iconRatioGood())}">
      <nz-upload class="thumb-uploader" nzFileType="image/png,image/jpeg,image/jpg" nzAccept="image/png,image/jpeg,image/jpg"
        nzListType="picture-card" [nzShowUploadList]="false" [nzBeforeUpload]="beforeIconUpload">
        <img class="preview" [src]="iconImage ? iconImage.src : collection?.icon"/>
      </nz-upload>
    </div>
    <div *ngIf="iconFile && iconImage" class="text-secondary text-center">
      <small>{{iconFile.size | dataSize}}, {{iconFile.type}}, {{iconImage.width + 'x' + iconImage.height}}</small>
    </div>
  </div>
  <div>
    <div *ngIf="coverFile && !coverRatioGood()" class="text-danger" i18n>
      尺寸错误: 要求宽高比：2:1
    </div>
    <div *ngIf="coverFile && !coverSizeGood()" class="text-danger" i18n>
      图片大小超过限制（最大允许2M）
    </div>
    <div class="upload-box-cover" [ngClass]="{'bad': iconFile && (!coverSizeGood() || !coverRatioGood())}">
      <nz-upload class="thumb-uploader" nzFileType="image/png,image/jpeg,image/jpg" nzAccept="image/png,image/jpeg,image/jpg"
        nzListType="picture-card" [nzShowUploadList]="false" [nzBeforeUpload]="beforeHeaderUpload">
        <img class="preview" [src]="coverImage ? coverImage.src : collection?.cover"/>
      </nz-upload>
    </div>
    <div *ngIf="coverFile && coverImage" class="text-secondary text-center">
      <small>{{coverFile.size | dataSize}}, {{coverFile.type}}, {{coverImage.width + 'x' + coverImage.height}}</small>
    </div>
  </div>

  <div class="d-flex flex-column flex-grow-1 ms-4">

    <nz-form-item class="mt-2">
      <nz-form-label nzFor="title" i18n>名称</nz-form-label>
      <editable (save)="null" (cancel)="null" class="d-flex align-items-center">
        <ng-template viewMode>
          <span  i18n>{{title}}</span>
          <button class="btn btn-sm border-0"> <i class="fal fa-edit"></i> </button>
        </ng-template>
        <ng-template editMode>
          <nz-form-control i18n-nzErrorTip nzErrorTip="请选择多语翻译">
          <nz-select id="title" formControlName="title" i18n-nzPlaceHolder nzPlaceHolder="请选择多语言">
            <nz-option *ngFor="let item of translateOptions; let i=index" [nzValue]="item.value" [nzLabel]="item.label"></nz-option>
          </nz-select>
        </nz-form-control>
        </ng-template>
      </editable>
    </nz-form-item>

    <nz-form-item>
      <nz-form-label nzFor="tag" i18n>TAG</nz-form-label>
      <editable (save)="null" (cancel)="null" class="d-flex align-items-center">
        <ng-template viewMode>
          <span  i18n>{{f['tag'].value}}</span>
          <button class="btn btn-sm border-0"> <i class="fal fa-edit"></i> </button>
        </ng-template>
        <ng-template editMode>
          <nz-form-control i18n-nzErrorTip nzErrorTip="请输入绑定的标签">
            <input nz-input formControlName="tag" id="tag" i18n-placeHolder placeHolder="收集唯一标识，如horse, baby等">
          </nz-form-control>
        </ng-template>
      </editable>
    </nz-form-item>

    <nz-form-item>
      <nz-form-label nzFor="slogon" i18n>Slogon</nz-form-label>
      <editable (save)="null" (cancel)="null" class="d-flex align-items-center">
        <ng-template viewMode>
          <span  i18n>{{slogon}}</span>
          <button class="btn btn-sm border-0"> <i class="fal fa-edit"></i> </button>
        </ng-template>
        <ng-template editMode>
          <nz-form-control i18n-nzErrorTip nzErrorTip="请选择多语翻译">
          <nz-select id="slogon" formControlName="slogon" i18n-nzPlaceHolder nzPlaceHolder="请选择多语言">
            <nz-option *ngFor="let item of translateOptions; let i=index" [nzValue]="item.value" [nzLabel]="item.label"></nz-option>
          </nz-select>
        </nz-form-control>
        </ng-template>
      </editable>
    </nz-form-item>

    <nz-form-item>
      <nz-form-label nzFor="hint" i18n>奖励提示数</nz-form-label>
      <editable (save)="null" (cancel)="null" class="d-flex align-items-center">
        <ng-template viewMode>
          <span  i18n>{{f['hint'].value}}</span>
          <button class="btn btn-sm border-0"> <i class="fal fa-edit"></i> </button>
        </ng-template>
        <ng-template editMode>
          <nz-form-control i18n-nzErrorTip nzErrorTip="奖励提示数">
          <input nz-input formControlName="hint" id="hint" i18n-nzPlaceHolder nzPlaceHolder="奖励提示数">
        </nz-form-control>
        </ng-template>
      </editable>
    </nz-form-item>

    <nz-form-item>
      <nz-form-label nzFor="order" i18n>排序</nz-form-label>
      <editable (save)="null" (cancel)="null" class="d-flex align-items-center">
        <ng-template viewMode>
          <span  i18n>{{f['order'].value}}</span>
          <button class="btn btn-sm border-0"> <i class="fal fa-edit"></i> </button>
        </ng-template>
        <ng-template editMode>
          <nz-form-control i18n-nzErrorTip nzErrorTip="排序">
          <input nz-input formControlName="order" id="order" i18n-nzPlaceHolder nzPlaceHolder="排序">
        </nz-form-control>
        </ng-template>
      </editable>
    </nz-form-item>

    <nz-form-item>
      <nz-form-label nzFor="enabled" i18n>启用</nz-form-label>
      <nz-form-control i18n-nzErrorTip nzErrorTip="">
        <nz-switch nzSize="small" formControlName="enabled" id="enabled"></nz-switch>
      </nz-form-control>
    </nz-form-item>

    <nz-form-item>
      <nz-form-label i18n>内容数量</nz-form-label>
      <nz-form-control>
        {{f['contents'].value.length}}
      </nz-form-control>
    </nz-form-item>


  </div>
</div>

<div nz-row [nzGutter]="[20, 20]" nzAlign="top" class="ms-2 mt-2" 
  cdkDropListGroup>
  <div cdkDropList [cdkDropListData]="i" *ngFor="let item of form.controls['contents'].value; let i = index;" 
    nz-col  [nzSm]="8" [nzMd]="6" [nzLg]="6" [nzXl]="4" [nzXXl]="3"	>
    <art-card cdkDrag [cdkDragData]="i" (cdkDragEntered)="entered($event)"
      [data]="item"  
      [hideAuthor]="false"
      [showTrash]="true"
      (onTrash)="onRemoveContent($event)">
    </art-card>
  </div>
  <div nz-col  [nzSm]="8" [nzMd]="6" [nzLg]="6" [nzXl]="4" [nzXXl]="3" 
    class="d-flex flex-column justify-content-center align-items-center flex-grow-1"
    (click)="onAddContent()">
     <div class="blank-content d-flex flex-column justify-content-center align-items-center">
      <span><i class="fal fa-plus me-1" ></i><ng-container i18n>添加内容</ng-container></span>
    </div>
  </div>
</div>

</form>


</nz-spin>

  `,
  styles: [
    `
  .upload-box-icon {
    display: flex;
    width: 250px;
    height: 250px;
    padding: 8px;
  }

  .upload-box-cover {
    display: flex;
    width: 500px;
    height: 250px;
    padding: 8px;
  }

  .bad {
    border:2px dashed #ccc;
    border-radius:6px;
    border-color:#cc0000;
  }

  .good{
    border:2px dashed #ccc;
    border-radius:6px;
    border-color:#00cc00;
  }

  .preview {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;  
  }

  nz-select {
    min-width: 500px;
  }

  :host ::ng-deep .thumb-uploader > .ant-upload {
    width: 100%;
    height:100%;
    /* aspect-ratio: 1 / 1; */
  }

  .ant-form-item {
    margin-bottom: 5px;
  }

  .title {
    font-weight: 600;
    font-size: 16px;
    line-height: 28px;
  }

  .blank-content {
    box-sizing: border-box;
    background-color: #eee;
    width: 100%;
    height: 100%;
    aspect-ratio: 1 / 1;
    cursor : pointer;
  }


  .cdk-drag-preview {
    box-sizing: border-box;
    border-radius: 4px;
    box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
                0 8px 10px 1px rgba(0, 0, 0, 0.14),
                0 3px 14px 2px rgba(0, 0, 0, 0.12);
  }

  .cdk-drag-placeholder {
    opacity: 0;
  }

  .cdk-drag-animating {
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
  }

    `
  ]
})
export class CollectionDetailComponent implements OnInit {

  id: string;
  collection: any;
  title: string;
  slogon: string;

  history: string[] = [];
  previousUrl: string;

  form: FormGroup;
  iconFile: File;
  iconImage: HTMLImageElement;
  coverFile: File;
  coverImage: HTMLImageElement;

  translateOptions: any[] = [];


  get f() { return this.form.controls }
  
  //////////////////////////////// upload ///////////////////////////////
  iconSizeGood() {
    if (this.iconFile && this.iconFile.size > 1025 * 1024 * 2) return false;
    return true;
  }

  iconRatioGood() {
    if (this.iconImage && this.iconImage.width == this.iconImage.height) return true;
    return false;
  }

  beforeIconUpload = (file: NzUploadFile): boolean => {
    this.iconFile = file as unknown as File;
    Utils.blobToImage(this.iconFile).then(img => {
      this.iconImage = img;
      this.form.markAsDirty();
    })
    return false;
  };

  coverSizeGood() {
    if (this.coverFile && this.coverFile.size > 1025 * 1024 * 2) return false;
    return true;
  }

  coverRatioGood() {
    if (this.coverImage && this.coverImage.width == this.coverImage.height * 2) return true;
    return false;
  }

  beforeHeaderUpload = (file: NzUploadFile): boolean => {
    this.coverFile = file as unknown as File;
    Utils.blobToImage(this.coverFile).then(img => {
      this.coverImage = img;
      this.form.markAsDirty();
    })
    return false;
  };


  

  constructor(
    public collectionService: CollectionService,
    private fb: FormBuilder,
    private activatedRoute: ActivatedRoute,
    public message: NzMessageService,
    public modal: NzModalService,
    private router: Router,
    private location: Location,
  ) {
    this.form = this.fb.group({
      tag: [null, [Validators.required]],
      hint: [2, [Validators.required]],
      order: [1000, [Validators.required]],
      title: [null, [Validators.required]],
      enabled: [false, [Validators.required]],
      slogon: [null],
      contents: [[],],
    })

    this.form.controls['title'].valueChanges.subscribe(v => {
      let lable: string = this.translateOptions?.find(e => e.value == v)?.label;
      if (lable) {
        let idx = lable.lastIndexOf('|');
        if (idx >= 0) {
          this.title = lable.substring(idx + 1);
        }
      }
    })

    this.form.controls['slogon'].valueChanges.subscribe(v => {
      let lable: string = this.translateOptions?.find(e => e.value == v)?.label;
      if (lable) {
        let idx = lable.lastIndexOf('|');
        if (idx >= 0) {
          this.slogon = lable.substring(idx + 1);
        }
      }
    })

    this.id = this.activatedRoute.snapshot.params['id'];

    firstValueFrom(this.collectionService.translateOptions()).then((resp: any[]) => {
      this.translateOptions = resp;
    }) 

    this.loadData();
    
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        this.history.push(event.urlAfterRedirects);
      }
    })

  }

  error: HttpErrorResponse;
  isLoading: boolean = false;

  loadData() {
    this.isLoading = true;
    this.collectionService.get(this.id).subscribe({
      next: (resp: any) => { 
        this.collection = resp;
        this.title = this.collection.title?.zh;
        this.slogon = this.collection.slogon?.zh;
        this.form.controls['tag'].setValue(resp.tag);
        this.form.controls['hint'].setValue(resp.hint);
        this.form.controls['order'].setValue(resp.order);
        this.form.controls['enabled'].setValue(resp.enabled);
        this.form.controls['contents'].setValue(resp.contents);
        this.form.controls['title'].setValue(resp.title?._id);
        this.form.controls['slogon'].setValue(resp.slogon?._id);
        this.error = null; 
      },
      error: (err) => { this.error = err; this.isLoading = false; },
      complete: () => { this.isLoading = false }
    })
  }

  ngOnInit(): void {
  }


  onReturn() {
    this.history.pop();
    if (this.history.length >= 0) {
      this.router.navigateByUrl('/coloring/collection').then(() => {
        if (this.saved) window.location.reload();
      });
      // this.location.back();
    } else {
      this.router.navigateByUrl('/');
    }
  }

  saved: boolean = false;
  onSave() {
    if (this.form.invalid) {
      FormUtils.markAsDirty(this.form);
      return;
    }
    this.isLoading = true;
    let formData = this.getFormData();
    firstValueFrom(this.collectionService.update(formData, this.collection._id))
      .then(res => {
        this.loadData();
        this.message.success($localize`保存成功`);
        this.form.markAsPristine();
        this.saved = true;
      })
      .catch(err => {
        this.message.error(err.error?.message || err.message);
      }).then(() => {
        this.isLoading = false;
      })
  }

  getFormData() {
    let formData = new FormData();

    if (this.f['tag'].dirty && this.f['tag'].valid) formData.append('tag', this.f['tag'].value);
    if (this.f['hint'].dirty && this.f['hint'].valid) formData.append('hint', this.f['hint'].value);
    if (this.f['order'].dirty && this.f['order'].valid) formData.append('order', this.f['order'].value);
    if (this.f['title'].dirty && this.f['title'].valid) formData.append('title', this.f['title'].value);
    if (this.f['slogon'].dirty && this.f['slogon'].valid) formData.append('slogon', this.f['slogon'].value);
    if (this.f['enabled'].dirty && this.f['enabled'].valid) formData.append('enabled', this.f['enabled'].value);
    if (this.f['contents'].dirty && this.f['contents'].valid) { // 处理下contents，只留下id
      let contentIds = this.f['contents'].value.map(e => e._id);
      if (!contentIds || contentIds.length <= 0) {
        formData.append(`contents`, 'null');
      } else {
        contentIds.forEach((v, i) => {
          formData.append(`contents[${i}]`, v);
        })
      }
    }

    if (this.iconFile) {
      formData.append('icon', this.iconFile);
    }
    if (this.coverFile) {
      formData.append('cover', this.coverFile);
    }
    return formData;
  }


  onReset() {

  }

  remove() { return this.collectionService.remove(this.id) }


  onAddContent() {
    this.modal.create({
      nzTitle: $localize`选择内容加入收集`,
      nzCentered: true,
      nzWidth: '90vw',
      nzContent: CollectionAddContentComponent,
      nzComponentParams: {
        id: this.id,
      },
      nzOnOk: (component) => {
        if (component.selectContents && component.selectContents.length > 0) {
          let selectContents = component.selectContents.filter(c => this.f['contents'].value.findIndex(e => e._id == c._id) < 0); // 去重
          let newContents = this.f['contents'].value.concat(selectContents);
          this.f['contents'].setValue(newContents);
          this.f['contents'].markAsDirty();
        }
      }
    })
  }

  onRemoveContent(item) {
    console.log(item);
    let contents = this.f['contents'].value;
    let idx = contents.findIndex(e => e == item);
    if (idx >= 0) {
      contents.splice(idx, 1);
    }
    this.f['contents'].setValue(contents);
    this.f['contents'].markAsDirty();
  }


  drop(event: CdkDragDrop<string[]>) {
    console.log(event);
    let contents = this.f['contents'].value;
    moveItemInArray(contents, event.previousIndex, event.currentIndex);
    this.f['contents'].setValue(contents);
    this.f['contents'].markAsDirty();
  }
 

  entered(event: CdkDragEnter) {
    console.log("preIndex=" + event.item.data + "  curIndex=" + event.container.data);
    let contents = this.f['contents'].value;
    moveItemInArray(contents, event.item.data, event.container.data);
    this.f['contents'].setValue(contents);
    this.f['contents'].markAsDirty();
  }


}
