<script lang="ts">
  import { configStore, type HikariConfig } from "$lib/stores/config";
  import { formattedStats } from "$lib/stores/stats";
  import { achievementsStore } from "$lib/stores/achievements";
  import { open, save } from "@tauri-apps/plugin-dialog";
  import { writeFile, readFile } from "@tauri-apps/plugin-fs";

  export let onClose: () => void;

  let config: HikariConfig;
  configStore.config.subscribe((c) => (config = c));

  let editingName = false;
  let editingBio = false;
  let nameInput = "";
  let bioInput = "";
  let avatarDataUrl: string | null = null;

  // Initialize inputs when config is loaded
  $: if (config) {
    if (!editingName) nameInput = config.profile_name || "";
    if (!editingBio) bioInput = config.profile_bio || "";
  }

  // Load avatar on mount and when path changes
  let lastLoadedPath: string | null = null;

  async function updateAvatarDisplay(path: string | null) {
    if (path === lastLoadedPath) return;
    lastLoadedPath = path;
    if (path) {
      avatarDataUrl = await loadAvatarAsDataUrl(path);
    } else {
      avatarDataUrl = null;
    }
  }

  $: updateAvatarDisplay(config?.profile_avatar_path ?? null);

  let isGeneratingImage = false;

  $: unlockedCount = Object.values($achievementsStore.achievements).filter(
    (a) => a.unlocked
  ).length;
  $: totalAchievements = Object.values($achievementsStore.achievements).length;
  $: achievementPercentage =
    totalAchievements > 0 ? Math.round((unlockedCount / totalAchievements) * 100) : 0;

  async function selectAvatar() {
    try {
      const selected = await open({
        multiple: false,
        filters: [
          {
            name: "Images",
            extensions: ["png", "jpg", "jpeg", "gif", "webp"],
          },
        ],
      });

      if (selected && typeof selected === "string") {
        await configStore.updateConfig({ profile_avatar_path: selected });
      }
    } catch (error) {
      console.error("Failed to select avatar:", error);
    }
  }

  async function removeAvatar() {
    await configStore.updateConfig({ profile_avatar_path: null });
  }

  async function saveName() {
    await configStore.updateConfig({ profile_name: nameInput || null });
    editingName = false;
  }

  async function saveBio() {
    await configStore.updateConfig({ profile_bio: bioInput || null });
    editingBio = false;
  }

  async function loadAvatarAsDataUrl(path: string): Promise<string | null> {
    try {
      const data = await readFile(path);
      const extension = path.split(".").pop()?.toLowerCase() || "png";
      const mimeType =
        extension === "jpg" || extension === "jpeg"
          ? "image/jpeg"
          : extension === "gif"
            ? "image/gif"
            : extension === "webp"
              ? "image/webp"
              : "image/png";
      // Convert Uint8Array to base64 in chunks to avoid stack overflow
      const blob = new Blob([data], { type: mimeType });
      return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result as string);
        reader.onerror = () => resolve(null);
        reader.readAsDataURL(blob);
      });
    } catch (error) {
      console.error("Failed to load avatar:", error);
      return null;
    }
  }

  async function generateShareImage(): Promise<Blob> {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d")!;

    // Card dimensions (1080p for sharing)
    const width = 1920;
    const height = 1080;
    canvas.width = width;
    canvas.height = height;

    // Background gradient (dark theme)
    const bgGradient = ctx.createLinearGradient(0, 0, width, height);
    bgGradient.addColorStop(0, "#1a1a2e");
    bgGradient.addColorStop(1, "#16213e");
    ctx.fillStyle = bgGradient;
    ctx.fillRect(0, 0, width, height);

    // Trans flag stripe accent at top
    const stripeHeight = 25;
    const stripeColors = ["#5bcefa", "#f5a9b8", "#ffffff", "#f5a9b8", "#5bcefa"];
    stripeColors.forEach((color, i) => {
      ctx.fillStyle = color;
      ctx.fillRect(0, i * (stripeHeight / 5) * 2, width, (stripeHeight / 5) * 2);
    });

    // Border
    ctx.strokeStyle = "#5bcefa";
    ctx.lineWidth = 6;
    ctx.strokeRect(3, 3, width - 6, height - 6);

    // Avatar circle
    const avatarX = 200;
    const avatarY = 220;
    const avatarRadius = 140;

    ctx.save();
    ctx.beginPath();
    ctx.arc(avatarX, avatarY, avatarRadius, 0, Math.PI * 2);
    ctx.closePath();
    ctx.clip();

    // Draw avatar if available, otherwise gradient placeholder
    let avatarLoaded = false;
    if (config.profile_avatar_path) {
      try {
        const dataUrl = await loadAvatarAsDataUrl(config.profile_avatar_path);
        if (dataUrl) {
          const img = new Image();
          await new Promise<void>((resolve, reject) => {
            img.onload = () => resolve();
            img.onerror = () => reject();
            img.src = dataUrl;
          });
          ctx.drawImage(
            img,
            avatarX - avatarRadius,
            avatarY - avatarRadius,
            avatarRadius * 2,
            avatarRadius * 2
          );
          avatarLoaded = true;
        }
      } catch {
        // Will use fallback gradient
      }
    }

    if (!avatarLoaded) {
      const avatarGradient = ctx.createLinearGradient(
        avatarX - avatarRadius,
        avatarY - avatarRadius,
        avatarX + avatarRadius,
        avatarY + avatarRadius
      );
      avatarGradient.addColorStop(0, "#5bcefa");
      avatarGradient.addColorStop(0.5, "#f5a9b8");
      avatarGradient.addColorStop(1, "#5bcefa");
      ctx.fillStyle = avatarGradient;
      ctx.fillRect(
        avatarX - avatarRadius,
        avatarY - avatarRadius,
        avatarRadius * 2,
        avatarRadius * 2
      );
    }
    ctx.restore();

    // Avatar border
    ctx.beginPath();
    ctx.arc(avatarX, avatarY, avatarRadius + 6, 0, Math.PI * 2);
    ctx.strokeStyle = "#f5a9b8";
    ctx.lineWidth = 8;
    ctx.stroke();

    // Name
    ctx.fillStyle = "#ffffff";
    ctx.font = "bold 72px system-ui, -apple-system, sans-serif";
    ctx.fillText(config.profile_name || "Hikari User", 400, 180);

    // Bio (truncated)
    ctx.fillStyle = "#9ca3af";
    ctx.font = "36px system-ui, -apple-system, sans-serif";
    const bio = config.profile_bio || "A Hikari Desktop user";
    const truncatedBio = bio.length > 100 ? bio.substring(0, 97) + "..." : bio;
    ctx.fillText(truncatedBio, 400, 260);

    // Stats section
    const statsY = 420;
    ctx.fillStyle = "#6b7280";
    ctx.font = "bold 32px system-ui, -apple-system, sans-serif";
    ctx.fillText("LIFETIME STATS", 80, statsY);

    // Stats grid
    const stats = [
      { label: "Messages", value: $formattedStats.messagesTotal },
      { label: "Tokens", value: $formattedStats.totalTokens },
      { label: "Code Blocks", value: $formattedStats.codeBlocksTotal },
      { label: "Files Edited", value: $formattedStats.filesEditedTotal },
      { label: "Files Created", value: $formattedStats.filesCreatedTotal },
      { label: "Total Cost", value: $formattedStats.totalCost },
    ];

    const statBoxWidth = 540;
    const statBoxHeight = 160;
    const statsPerRow = 3;
    const startX = 80;
    const startY = statsY + 40;

    stats.forEach((stat, i) => {
      const row = Math.floor(i / statsPerRow);
      const col = i % statsPerRow;
      const x = startX + col * (statBoxWidth + 50);
      const y = startY + row * (statBoxHeight + 30);

      // Stat box background
      ctx.fillStyle = "rgba(255, 255, 255, 0.05)";
      ctx.beginPath();
      ctx.roundRect(x, y, statBoxWidth, statBoxHeight, 20);
      ctx.fill();

      // Stat value
      ctx.fillStyle = "#5bcefa";
      ctx.font = "bold 56px system-ui, -apple-system, sans-serif";
      ctx.fillText(stat.value, x + 32, y + 75);

      // Stat label
      ctx.fillStyle = "#9ca3af";
      ctx.font = "28px system-ui, -apple-system, sans-serif";
      ctx.fillText(stat.label.toUpperCase(), x + 32, y + 128);
    });

    // Achievement progress
    const achieveY = 870;
    ctx.fillStyle = "#6b7280";
    ctx.font = "bold 32px system-ui, -apple-system, sans-serif";
    ctx.fillText("ACHIEVEMENTS", 80, achieveY);

    // Progress bar background
    const progressX = 80;
    const progressY = achieveY + 30;
    const progressWidth = 1200;
    const progressHeight = 44;

    ctx.fillStyle = "rgba(255, 255, 255, 0.1)";
    ctx.beginPath();
    ctx.roundRect(progressX, progressY, progressWidth, progressHeight, 22);
    ctx.fill();

    // Progress bar fill
    const progressGradient = ctx.createLinearGradient(progressX, 0, progressX + progressWidth, 0);
    progressGradient.addColorStop(0, "#5bcefa");
    progressGradient.addColorStop(0.5, "#f5a9b8");
    progressGradient.addColorStop(1, "#5bcefa");
    ctx.fillStyle = progressGradient;
    ctx.beginPath();
    ctx.roundRect(
      progressX,
      progressY,
      progressWidth * (achievementPercentage / 100),
      progressHeight,
      22
    );
    ctx.fill();

    // Progress text
    ctx.fillStyle = "#ffffff";
    ctx.font = "bold 36px system-ui, -apple-system, sans-serif";
    ctx.fillText(
      `${unlockedCount} / ${totalAchievements} (${achievementPercentage}%)`,
      progressX + progressWidth + 40,
      progressY + 34
    );

    // Hikari branding
    ctx.fillStyle = "#f5a9b8";
    ctx.font = "bold 42px system-ui, -apple-system, sans-serif";
    ctx.fillText("✨ Hikari Desktop", 80, height - 100);

    // Discord promo
    ctx.fillStyle = "#9ca3af";
    ctx.font = "34px system-ui, -apple-system, sans-serif";
    ctx.fillText("Join our community: chat.nhcarrigan.com", 80, height - 45);

    // Convert canvas to blob
    return new Promise((resolve) => {
      canvas.toBlob((blob) => resolve(blob!), "image/png");
    });
  }

  async function shareProfile() {
    isGeneratingImage = true;
    try {
      const blob = await generateShareImage();
      const arrayBuffer = await blob.arrayBuffer();
      const uint8Array = new Uint8Array(arrayBuffer);

      const filePath = await save({
        filters: [{ name: "PNG Image", extensions: ["png"] }],
        defaultPath: `hikari-profile-${config.profile_name?.replace(/\s+/g, "-").toLowerCase() || "user"}.png`,
      });

      if (filePath) {
        await writeFile(filePath, uint8Array);
      }
    } catch (error) {
      console.error("Failed to generate share image:", error);
    } finally {
      isGeneratingImage = false;
    }
  }
</script>

<div class="profile-overlay" role="dialog" aria-modal="true">
  <div class="profile-panel">
    <div class="profile-header">
      <h2>Profile</h2>
      <button class="close-btn" on:click={onClose} aria-label="Close profile">
        <svg
          width="20"
          height="20"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        >
          <path d="M18 6L6 18M6 6l12 12" />
        </svg>
      </button>
    </div>

    <div class="profile-content">
      <!-- Avatar Section -->
      <div class="avatar-section">
        <div
          class="avatar-container"
          on:click={selectAvatar}
          role="button"
          tabindex="0"
          on:keydown={(e) => e.key === "Enter" && selectAvatar()}
        >
          {#if avatarDataUrl}
            <img src={avatarDataUrl} alt="Profile avatar" class="avatar-image" />
            <div class="avatar-overlay">
              <span>Change</span>
            </div>
          {:else}
            <div class="avatar-placeholder">
              <svg
                width="48"
                height="48"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="1.5"
              >
                <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
                <circle cx="12" cy="7" r="4" />
              </svg>
              <span>Add Photo</span>
            </div>
          {/if}
        </div>
        {#if config.profile_avatar_path}
          <button class="remove-avatar-btn" on:click={removeAvatar}>Remove Photo</button>
        {/if}
      </div>

      <!-- Name Section -->
      <div class="name-section">
        {#if editingName}
          <input
            type="text"
            bind:value={nameInput}
            placeholder="Enter your name"
            class="name-input"
            on:keydown={(e) => e.key === "Enter" && saveName()}
            on:blur={saveName}
          />
        {:else}
          <button
            class="name-display"
            on:click={() => {
              editingName = true;
              nameInput = config.profile_name || "";
            }}
          >
            <span class="name-text">{config.profile_name || "Click to add name"}</span>
            <svg
              width="16"
              height="16"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
            >
              <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
              <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
            </svg>
          </button>
        {/if}
      </div>

      <!-- Bio Section -->
      <div class="bio-section">
        <h3>Bio</h3>
        {#if editingBio}
          <textarea
            bind:value={bioInput}
            placeholder="Tell us about yourself..."
            class="bio-input"
            rows="3"
            on:blur={saveBio}
          ></textarea>
          <button class="save-bio-btn btn-trans-gradient" on:click={saveBio}>Save</button>
        {:else}
          <button
            class="bio-display"
            on:click={() => {
              editingBio = true;
              bioInput = config.profile_bio || "";
            }}
          >
            <span class="bio-text">{config.profile_bio || "Click to add a bio..."}</span>
          </button>
        {/if}
      </div>

      <!-- Stats Section -->
      <div class="stats-section">
        <h3>Lifetime Stats</h3>
        <div class="stats-grid">
          <div class="stat-card">
            <span class="stat-value">{$formattedStats.messagesTotal}</span>
            <span class="stat-label">Messages</span>
          </div>
          <div class="stat-card">
            <span class="stat-value">{$formattedStats.totalTokens}</span>
            <span class="stat-label">Tokens</span>
          </div>
          <div class="stat-card">
            <span class="stat-value">{$formattedStats.codeBlocksTotal}</span>
            <span class="stat-label">Code Blocks</span>
          </div>
          <div class="stat-card">
            <span class="stat-value">{$formattedStats.filesEditedTotal}</span>
            <span class="stat-label">Files Edited</span>
          </div>
          <div class="stat-card">
            <span class="stat-value">{$formattedStats.filesCreatedTotal}</span>
            <span class="stat-label">Files Created</span>
          </div>
          <div class="stat-card">
            <span class="stat-value">{$formattedStats.totalCost}</span>
            <span class="stat-label">Total Cost</span>
          </div>
        </div>
      </div>

      <!-- Achievements Section -->
      <div class="achievements-section">
        <h3>Achievements</h3>
        <div class="achievement-progress">
          <div class="progress-bar">
            <div class="progress-fill" style="width: {achievementPercentage}%"></div>
          </div>
          <span class="progress-text"
            >{unlockedCount} / {totalAchievements} ({achievementPercentage}%)</span
          >
        </div>
      </div>

      <!-- Share Section -->
      <div class="share-section">
        <button
          class="share-btn btn-trans-gradient"
          on:click={shareProfile}
          disabled={isGeneratingImage}
        >
          {#if isGeneratingImage}
            <span class="spinner"></span>
            Generating...
          {:else}
            <svg
              width="18"
              height="18"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
            >
              <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" />
              <polyline points="16 6 12 2 8 6" />
              <line x1="12" y1="2" x2="12" y2="15" />
            </svg>
            Share Profile
          {/if}
        </button>
        <p class="share-hint">Generate a shareable image of your profile</p>
      </div>
    </div>
  </div>
</div>

<style>
  .profile-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    backdrop-filter: blur(4px);
  }

  .profile-panel {
    background: var(--bg-secondary);
    border-radius: 16px;
    width: 90%;
    max-width: 480px;
    max-height: 85vh;
    overflow-y: auto;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
    border: 1px solid var(--border-color);
  }

  .profile-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 24px;
    border-bottom: 1px solid var(--border-color);
    position: sticky;
    top: 0;
    background: var(--bg-secondary);
    z-index: 1;
  }

  .profile-header h2 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    color: var(--text-primary);
  }

  .close-btn {
    background: none;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 4px;
    border-radius: 4px;
    transition: all 0.2s;
  }

  .close-btn:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
  }

  .profile-content {
    padding: 24px;
    display: flex;
    flex-direction: column;
    gap: 24px;
  }

  /* Avatar */
  .avatar-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
  }

  .avatar-container {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    overflow: hidden;
    cursor: pointer;
    position: relative;
    background: var(--bg-tertiary);
    border: 3px solid var(--trans-pink);
    box-shadow: 0 0 20px rgba(245, 169, 184, 0.3);
    transition: all 0.3s;
  }

  .avatar-container:hover {
    border-color: var(--trans-blue);
    box-shadow: 0 0 30px rgba(91, 206, 250, 0.4);
    transform: scale(1.02);
  }

  .avatar-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .avatar-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.2s;
    color: white;
    font-size: 14px;
    font-weight: 500;
  }

  .avatar-container:hover .avatar-overlay {
    opacity: 1;
  }

  .avatar-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--text-secondary);
  }

  .avatar-placeholder span {
    font-size: 12px;
  }

  .remove-avatar-btn {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 12px;
    cursor: pointer;
    text-decoration: underline;
  }

  .remove-avatar-btn:hover {
    color: var(--trans-pink);
  }

  /* Name */
  .name-section {
    text-align: center;
  }

  .name-display {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 8px 16px;
    border-radius: 8px;
    transition: all 0.2s;
  }

  .name-display:hover {
    background: var(--bg-tertiary);
  }

  .name-display svg {
    color: var(--text-secondary);
    opacity: 0;
    transition: opacity 0.2s;
  }

  .name-display:hover svg {
    opacity: 1;
  }

  .name-text {
    font-size: 24px;
    font-weight: 600;
    color: var(--text-primary);
  }

  .name-input {
    width: 100%;
    max-width: 300px;
    padding: 12px 16px;
    font-size: 24px;
    font-weight: 600;
    text-align: center;
    background: var(--bg-tertiary);
    border: 2px solid var(--trans-pink);
    border-radius: 8px;
    color: var(--text-primary);
    outline: none;
  }

  .name-input:focus {
    border-color: var(--trans-blue);
    box-shadow: 0 0 10px rgba(91, 206, 250, 0.3);
  }

  /* Bio */
  .bio-section h3,
  .stats-section h3,
  .achievements-section h3 {
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
  }

  .bio-display {
    width: 100%;
    text-align: left;
    background: var(--bg-tertiary);
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 12px;
    cursor: pointer;
    transition: all 0.2s;
  }

  .bio-display:hover {
    border-color: var(--border-color);
  }

  .bio-text {
    color: var(--text-secondary);
    font-size: 14px;
    line-height: 1.5;
  }

  .bio-input {
    width: 100%;
    padding: 12px;
    font-size: 14px;
    background: var(--bg-tertiary);
    border: 2px solid var(--trans-pink);
    border-radius: 8px;
    color: var(--text-primary);
    resize: none;
    outline: none;
    font-family: inherit;
  }

  .bio-input:focus {
    border-color: var(--trans-blue);
    box-shadow: 0 0 10px rgba(91, 206, 250, 0.3);
  }

  .save-bio-btn {
    margin-top: 8px;
    padding: 8px 16px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
  }

  /* Stats */
  .stats-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
  }

  .stat-card {
    background: var(--bg-tertiary);
    border-radius: 12px;
    padding: 16px 12px;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 4px;
    border: 1px solid var(--border-color);
  }

  .stat-value {
    font-size: 20px;
    font-weight: 700;
    color: var(--text-primary);
    background: linear-gradient(135deg, var(--trans-blue), var(--trans-pink));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }

  .stat-label {
    font-size: 11px;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
  }

  /* Achievements */
  .achievement-progress {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .progress-bar {
    height: 12px;
    background: var(--bg-tertiary);
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid var(--border-color);
  }

  .progress-fill {
    height: 100%;
    background: linear-gradient(
      90deg,
      var(--trans-blue),
      var(--trans-pink),
      var(--trans-white),
      var(--trans-pink),
      var(--trans-blue)
    );
    background-size: 200% 100%;
    animation: shimmer 3s linear infinite;
    border-radius: 6px;
    transition: width 0.5s ease;
  }

  @keyframes shimmer {
    0% {
      background-position: 200% 0;
    }
    100% {
      background-position: -200% 0;
    }
  }

  .progress-text {
    font-size: 14px;
    color: var(--text-secondary);
    text-align: center;
  }

  /* Share */
  .share-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border-color);
  }

  .share-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 24px;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    font-size: 15px;
    font-weight: 600;
    transition: all 0.2s;
  }

  .share-btn:disabled {
    opacity: 0.7;
    cursor: not-allowed;
  }

  .share-btn svg {
    flex-shrink: 0;
  }

  .share-hint {
    margin: 0;
    font-size: 12px;
    color: var(--text-secondary);
  }

  .spinner {
    width: 16px;
    height: 16px;
    border: 2px solid transparent;
    border-top-color: currentColor;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
  }

  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
</style>
