<script lang="ts">
  import domtoimage from "dom-to-image";
  import Cropper, { type OnCropCompleteEvent } from "svelte-easy-crop";
  import gradiImage from "$lib/images/image.png"

  let crop = { x: 0, y: 0 };
  let zoom = 1;
  let cropSize = { width: 512, height: 512 };
  let maxZoom = 10;
  let minZoom = 1;
  let restrictPosition = true;
  let showGrid = false;
  let croppedImage = null;

  let image: string;
  let incorrectImage: string;
  let text: string = "";
  let error: string = "";
  let isDragging: boolean = false;
  let isModalOpen: boolean = false;
  let fontSize: number = 2.5;

  async function validateAndLoadImage(file: File): Promise<void> {
    error = "";
    const img = new Image();
    const reader = new FileReader();

    reader.onload = (e: ProgressEvent<FileReader>) => {
      img.src = e.target?.result as string;
      img.onload = () => {
        if (img.width === 512 && img.height === 512) {
          image = e.target?.result as string;
        } else {
          incorrectImage = e.target?.result as string;
          isModalOpen = true;
        }
      };
    };
    reader.readAsDataURL(file);
  }

  function handleDrop(e: DragEvent): void {
    e.preventDefault();
    isDragging = false;
    const file = (e.dataTransfer as DataTransfer).files[0];
    if (file && file.type.startsWith("image/")) {
      validateAndLoadImage(file);
    }
  }

  function handleDragOver(e: DragEvent): void {
    e.preventDefault();
    isDragging = true;
  }

  function handleDragLeave(): void {
    isDragging = false;
  }

  async function saveImage(): Promise<void> {
    if (!image) return;

    let node = document.getElementById("result");

    if (node) {
      domtoimage
        .toPng(node, {
          style: {
            border: "none",
            padding: "0",
            margin: "0",
            outline: "none",
          },
        })
        .then((dataUrl: string) => {
          var link = document.createElement("a");
          link.download = "avatar.png";
          link.href = dataUrl;
          link.click();
        });
    }
  }

  function cropImage(x: number, y: number, width: number, height: number) {
    const img = new Image();
    img.src = incorrectImage;

    img.onload = () => {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      canvas.width = 512;
      canvas.height = 512;

      ctx.drawImage(img, x, y, width, height, 0, 0, 512, 512);

      croppedImage = canvas.toDataURL("image/png");
    };
  }

  const handleCropComplete = (event: OnCropCompleteEvent) => {
    const { x, y, width, height } = event.pixels;
    cropImage(x, y, width, height);
  };

  function saveToMainImage() {
    image = croppedImage;
    isModalOpen = false;
  }
</script>

<div>
  {#if isModalOpen}
    <div class="bg-white rounded-xl shadow-lg p-6">
      <div class="flex flex-col">
        <div class="h-[700px] w-[700px] relative rounded-2xl">
          <Cropper
            image={incorrectImage}
            {cropSize}
            {maxZoom}
            {minZoom}
            {restrictPosition}
            {showGrid}
            bind:crop
            bind:zoom
            oncropcomplete={handleCropComplete}
          />
        </div>

        <button
          onclick={saveToMainImage}
          class="px-6 py-3 bg-gradient-to-r from-purple-600 to-blue-600 text-white font-medium rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed mt-3"
        >
          Обрезать
        </button>
      </div>
    </div>
  {:else}
    <div class="bg-white rounded-xl shadow-lg p-6">
      <div
        class="preview-container relative bg-gray-50 mb-4 overflow-hidden border-2 transition-colors h-[512px] w-[512px] rounded-full"
        ondrop={handleDrop}
        ondragover={handleDragOver}
        ondragleave={handleDragLeave}
        style="cursor: pointer"
        onclick={() => document.getElementById("fileInput").click()}
      >
        <!-- Состояние без изображения -->
        {#if !image}
          <div
            class="absolute inset-0 flex flex-col items-center justify-center cursor-pointer"
          >
            <svg
              class="w-16 h-16 text-gray-400 mb-3"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                stroke-width="2"
                d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
              ></path>
            </svg>
            <p class="text-lg text-gray-500">Перетащите изображение</p>
            <p class="text-sm text-gray-400 mt-1">или кликните для выбора</p>
          </div>
        {/if}

        <!-- Загруженное изображение -->
        {#if image}
          <div id="result" class="w-full h-full">
            <svg viewBox="0 0 512 512" class="w-full h-full" style="--font-size: {fontSize}rem">
              <defs>
                <clipPath id="circle-clip">
                  <circle cx="256" cy="256" r="256" />
                </clipPath>

                <pattern id="imagePattern" patternUnits="userSpaceOnUse" width="512" height="512" >
                  <image href={gradiImage} width="512" height="512"/>
                </pattern>
              </defs>
              <image href={image} width="512" height="512" clip-path="url(#circle-clip)" />
              <!-- Текст -->
            {#if text}
                <path
                  id="text-path"
                  d="M 256,26 a 230,230 0 0,0 0,460 a 230,230 0 0,0 0,-460"
                  fill="none"
                />
    
                <text class="circle-text-bg">
                  <textPath href="#text-path" startOffset="50%" text-anchor="middle">{text}</textPath>
                </text>

                <text class="circle-text">
                  <textPath href="#text-path" startOffset="50%" text-anchor="middle">{text}</textPath>
                </text>
            {/if}
            </svg>
          </div>
        {/if}

        <input
          id="fileInput"
          type="file"
          accept="image/*"
          class="hidden"
          onchange={(e) =>
            validateAndLoadImage((e.target as HTMLInputElement).files[0])}
        />
      </div>

      {#if error}
        <p class="text-red-500 text-sm mb-4 text-center">{error}</p>
      {/if}

      <div class="flex flex-col sm:flex-row gap-3 mb-4">
        <input
          type="text"
          bind:value={text}
          placeholder="Должность"
          class="flex-grow px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
        />
        <button
          onclick={saveImage}
          class="px-6 py-3 bg-gradient-to-r from-purple-600 to-blue-600 text-white font-medium rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed"
        >
          Сохранить 512×512
        </button>
      </div>

      <div class="flex items-center gap-3 mb-4">
        <label for="font-size-slider" class="text-sm text-gray-600 whitespace-nowrap"
          >Размер текста:</label
        >
        <input
          id="font-size-slider"
          type="range"
          min="1.5"
          max="7"
          step="0.1"
          bind:value={fontSize}
          class="w-full"
        />
        <div class="min-w-[25px] min-h-[25px]">{fontSize}</div>
      </div>

      <p class="text-sm text-gray-500 text-center">
        Размер изображения 512×512 пикселей
      </p>
    </div>
  {/if}
</div>

<style>
  .circle-text-bg {
    fill: none;
    stroke: rgb(0, 0, 0, 0.7);
    stroke-width: 5px;
    stroke-linejoin:round;
    stroke-linecap:round;
    paint-order: stroke;
    font-size: var(--font-size);
    font-weight: 700;
    letter-spacing: 6px;
  }

  .circle-text {
    fill: url(#imagePattern);
    stroke: #000;
    stroke-width: 1.5px;
    paint-order: stroke;
    letter-spacing: 6px;
    font-size: var(--font-size);
    font-weight: 700;
  }

</style>
