import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-drawing',
  templateUrl: './drawing.component.html',
  styleUrls: ['./drawing.component.scss'],
  standalone: true,
  imports: [IonicModule, CommonModule, FormsModule],
})
export class DrawingComponent implements OnInit, AfterViewInit {
  @ViewChild('canvas') canvasRef!: ElementRef<HTMLCanvasElement>;
  private ctx!: CanvasRenderingContext2D;
  private isDrawing = false;
  private lastX = 0;
  private lastY = 0;

  currentColor = '#000000';
  currentWidth = 5;

  customColor = '#000000';
  showGrid = false;
  opacity = 1;
  smoothing = true;
  showLayers = false;
  currentLayer = 'layer1';

  layers = [
    { id: 'layer1', name: '图层 1', visible: true },
    { id: 'layer2', name: '图层 2', visible: true }
  ];

  history: ImageData[] = [];
  historyIndex = -1;

  tools = [
    { id: 'brush', icon: 'brush', name: '画笔' },
    { id: 'eraser', icon: 'trash', name: '橡皮擦' },
    { id: 'line', icon: 'remove', name: '直线' },
    { id: 'rect', icon: 'square-outline', name: '矩形' },
    { id: 'circle', icon: 'ellipse-outline', name: '圆形' },
    { id: 'clear', icon: 'refresh', name: '清空' }
  ];

  colors = [
    '#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff',
    '#ffff00', '#00ffff', '#ff00ff', '#808080', '#800000'
  ];

  selectedTool = 'brush';

  constructor() { }

  ngOnInit() { }

  ngAfterViewInit() {
    const canvas = this.canvasRef.nativeElement;
    this.ctx = canvas.getContext('2d')!;
    this.resizeCanvas();
    this.initializeCanvas();

    window.addEventListener('resize', () => {
      this.resizeCanvas();
    });
  }

  private resizeCanvas() {
    const canvas = this.canvasRef.nativeElement;
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 200; // 减去顶部工具栏的高度
  }

  private initializeCanvas() {
    this.ctx.fillStyle = '#ffffff';
    this.ctx.fillRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
  }

  startDrawing(event: TouchEvent | MouseEvent) {
    this.isDrawing = true;
    const pos = this.getPosition(event);
    this.lastX = pos.x;
    this.lastY = pos.y;
  }

  draw(event: TouchEvent | MouseEvent) {
    if (!this.isDrawing) return;
    event.preventDefault();

    const pos = this.getPosition(event);

    switch (this.selectedTool) {
      case 'brush':
      case 'eraser':
        this.drawFreehand(pos);
        break;
      case 'line':
        this.drawLine(pos);
        break;
      case 'rect':
        this.drawRect(pos);
        break;
      case 'circle':
        this.drawCircle(pos);
        break;
    }
  }

  private drawFreehand(pos: { x: number, y: number }) {
    this.ctx.beginPath();
    this.ctx.moveTo(this.lastX, this.lastY);
    this.ctx.lineTo(pos.x, pos.y);
    this.ctx.strokeStyle = this.selectedTool === 'eraser' ? '#ffffff' : this.currentColor;
    this.ctx.lineWidth = this.currentWidth;
    this.ctx.lineCap = 'round';
    this.ctx.stroke();

    this.lastX = pos.x;
    this.lastY = pos.y;
  }

  private drawLine(pos: { x: number, y: number }) {
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = this.canvasRef.nativeElement.width;
    tempCanvas.height = this.canvasRef.nativeElement.height;
    const tempCtx = tempCanvas.getContext('2d')!;

    tempCtx.drawImage(this.canvasRef.nativeElement, 0, 0);
    tempCtx.beginPath();
    tempCtx.moveTo(this.lastX, this.lastY);
    tempCtx.lineTo(pos.x, pos.y);
    tempCtx.strokeStyle = this.currentColor;
    tempCtx.lineWidth = this.currentWidth;
    tempCtx.stroke();

    this.ctx.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
    this.ctx.drawImage(tempCanvas, 0, 0);
  }

  private drawRect(pos: { x: number, y: number }) {
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = this.canvasRef.nativeElement.width;
    tempCanvas.height = this.canvasRef.nativeElement.height;
    const tempCtx = tempCanvas.getContext('2d')!;

    tempCtx.drawImage(this.canvasRef.nativeElement, 0, 0);
    tempCtx.beginPath();
    tempCtx.rect(this.lastX, this.lastY, pos.x - this.lastX, pos.y - this.lastY);
    tempCtx.strokeStyle = this.currentColor;
    tempCtx.lineWidth = this.currentWidth;
    tempCtx.stroke();

    this.ctx.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
    this.ctx.drawImage(tempCanvas, 0, 0);
  }

  private drawCircle(pos: { x: number, y: number }) {
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = this.canvasRef.nativeElement.width;
    tempCanvas.height = this.canvasRef.nativeElement.height;
    const tempCtx = tempCanvas.getContext('2d')!;

    const radius = Math.sqrt(
      Math.pow(pos.x - this.lastX, 2) + Math.pow(pos.y - this.lastY, 2)
    );

    tempCtx.drawImage(this.canvasRef.nativeElement, 0, 0);
    tempCtx.beginPath();
    tempCtx.arc(this.lastX, this.lastY, radius, 0, Math.PI * 2);
    tempCtx.strokeStyle = this.currentColor;
    tempCtx.lineWidth = this.currentWidth;
    tempCtx.stroke();

    this.ctx.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
    this.ctx.drawImage(tempCanvas, 0, 0);
  }

  stopDrawing() {
    if (this.isDrawing) {
      this.isDrawing = false;
      this.saveToHistory();
    }
  }

  private getPosition(event: TouchEvent | MouseEvent) {
    const canvas = this.canvasRef.nativeElement;
    const rect = canvas.getBoundingClientRect();

    let x, y;
    if (event instanceof TouchEvent) {
      x = event.touches[0].clientX - rect.left;
      y = event.touches[0].clientY - rect.top;
    } else {
      x = event.clientX - rect.left;
      y = event.clientY - rect.top;
    }

    return { x, y };
  }

  selectTool(toolId: string) {
    this.selectedTool = toolId;
    if (toolId === 'clear') {
      this.clearCanvas();
    }
  }

  selectColor(color: string) {
    this.currentColor = color;
    this.selectedTool = 'brush';
  }

  clearCanvas() {
    this.ctx.fillStyle = '#ffffff';
    this.ctx.fillRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
  }

  async saveDrawing() {
    const canvas = this.canvasRef.nativeElement;
    try {
      const dataUrl = canvas.toDataURL('image/png');
      const response = await fetch(dataUrl);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `绘画_${new Date().getTime()}.png`;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
      this.showToast('保存成功');
    } catch (error) {
      this.showToast('保存失败，请重试');
    }
  }

  private async showToast(message: string) {
    const toast = document.createElement('ion-toast');
    toast.message = message;
    toast.duration = 2000;
    toast.position = 'top';
    document.body.appendChild(toast);
    await toast.present();
  }

  undo() {
    if (this.historyIndex > 0) {
      this.historyIndex--;
      const imageData = this.history[this.historyIndex];
      this.ctx.putImageData(imageData, 0, 0);
    }
  }

  redo() {
    if (this.historyIndex < this.history.length - 1) {
      this.historyIndex++;
      const imageData = this.history[this.historyIndex];
      this.ctx.putImageData(imageData, 0, 0);
    }
  }

  saveToHistory() {
    this.historyIndex++;
    this.history = this.history.slice(0, this.historyIndex);
    this.history.push(this.ctx.getImageData(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height));
  }

  toggleGrid() {
    this.showGrid = !this.showGrid;
  }

  toggleOpacity() {
    this.opacity = this.opacity === 1 ? 0.5 : 1;
    this.ctx.globalAlpha = this.opacity;
  }

  toggleSmooth() {
    this.smoothing = !this.smoothing;
    this.ctx.imageSmoothingEnabled = this.smoothing;
  }

  toggleLayers() {
    this.showLayers = !this.showLayers;
  }

  addLayer() {
    const newId = `layer${this.layers.length + 1}`;
    this.layers.push({
      id: newId,
      name: `图层 ${this.layers.length + 1}`,
      visible: true
    });
    this.currentLayer = newId;
  }

  deleteLayer(layerId: string) {
    if (this.layers.length > 1) {
      this.layers = this.layers.filter(layer => layer.id !== layerId);
      if (this.currentLayer === layerId) {
        this.currentLayer = this.layers[0].id;
      }
    }
  }
}
