import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { ImageRecord, ImageService } from '../services/image.service';
import { AuthService } from '../auth/auth.service';
import { ToastService } from '../services/toast.service';

const PLACEHOLDER_SVG = `data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="800" height="500" viewBox="0 0 800 500"><rect width="800" height="500" fill="%23111"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="48" fill="%23444">&#x1F517;</text></svg>`;

@Component({
  selector: 'app-detail',
  standalone: true,
  imports: [CommonModule, FormsModule, RouterLink],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <!-- Loading skeleton -->
    <div class="detail-page" *ngIf="loading">
      <div class="skeleton image-skeleton"></div>
      <div class="chip-row-skeleton">
        <div *ngFor="let _ of skeletonChips" class="skeleton chip-skeleton"></div>
      </div>
      <div class="chip-row-skeleton">
        <div *ngFor="let _ of skeletonChips" class="skeleton chip-skeleton short"></div>
      </div>
    </div>

    <!-- Network error state -->
    <div class="fetch-error-card" *ngIf="error && !loading">
      <span class="error-icon">⚠</span>
      <p>Failed to load image. Please check your connection.</p>
      <div class="error-actions">
        <button class="retry-btn" (click)="retry()">Retry</button>
        <a routerLink="/" class="back-link">Back to library</a>
      </div>
    </div>

    <!-- Not-found state -->
    <div class="not-found-card" *ngIf="!image && !loading && !error">
      <span class="not-found-icon">✦</span>
      <h2>Image not found</h2>
      <p>This image may have been deleted or the URL is incorrect.</p>
      <a routerLink="/" class="back-btn">Back to library</a>
    </div>

    <!-- Main content -->
    <div class="detail-page" *ngIf="image && !loading">
      <button class="back-btn-inline" (click)="goBack()">← Back</button>
      <h2>{{ image.filename }}</h2>

      <img
        class="full-image"
        [src]="image.file_url"
        [alt]="image.filename"
        (error)="onImgError($event)"
      />

      <button class="copy-url-btn" (click)="copyUrl()">Copy URL</button>

      <section class="tags-section">
        <h3>Tags</h3>
        <div class="chips">
          <span *ngFor="let tag of image.tags" class="chip">
            {{ tag }} <button *ngIf="auth.isAuthenticated()" (click)="removeTag(tag)">×</button>
          </span>
        </div>
        <p class="tag-error" *ngIf="tagError">{{ tagError }}</p>
      </section>

      <section class="owner-actions" *ngIf="auth.isAuthenticated()">
        <div class="add-tag">
          <input
            [(ngModel)]="newTagInput"
            placeholder="Add tag…"
            (keydown.enter)="onEnter()"
            (blur)="onBlur()"
          />
        </div>
        <button class="delete-btn" (click)="showDeleteDialog = true">Delete Image</button>
      </section>

      <div class="dialog-overlay" *ngIf="showDeleteDialog">
        <div class="dialog">
          <p>Permanently delete this image?</p>
          <button (click)="confirmDelete()">Delete</button>
          <button (click)="cancelDelete()">Cancel</button>
        </div>
      </div>
    </div>
  `,
  styles: [`
    .detail-page { max-width: 900px; margin: 32px auto; padding: 0 16px; }

    /* Skeleton */
    .image-skeleton { width: 100%; height: 400px; margin-bottom: 16px; }
    .chip-row-skeleton { display: flex; gap: 8px; margin-bottom: 10px; padding: 0 16px; }
    .chip-skeleton { width: 64px; height: 28px; border-radius: var(--radius-chip); }
    .chip-skeleton.short { width: 48px; }

    /* Network error card */
    .fetch-error-card {
      max-width: 520px; margin: 80px auto; text-align: center;
      padding: 40px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    }
    .error-icon { display: block; font-size: 2rem; color: var(--danger); margin-bottom: 12px; }
    .error-actions { display: flex; justify-content: center; gap: 16px; margin-top: 20px; }
    .retry-btn { padding: 8px 20px; background: var(--surface-raised); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; }
    .retry-btn:hover { border-color: var(--border-focus); }
    .back-link { color: var(--accent); text-decoration: none; line-height: 2.2; }

    /* Not-found card */
    .not-found-card {
      max-width: 480px; margin: 80px auto; text-align: center;
      padding: 48px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    }
    .not-found-icon { display: block; font-size: 2.5rem; color: var(--text-muted); margin-bottom: 16px; }
    .not-found-card h2 { margin-bottom: 8px; }
    .not-found-card p { color: var(--text-muted); margin-bottom: 24px; }

    /* Main detail */
    .back-btn-inline { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 1rem; margin-bottom: 16px; padding: 0; }
    .back-btn {
      display: inline-block; margin-top: 16px; padding: 10px 24px;
      background: var(--surface-raised); color: var(--text);
      border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; text-decoration: none;
    }
    .back-btn:hover { border-color: var(--border-focus); }
    .full-image { width: 100%; max-height: 70vh; object-fit: contain; background: #111; border-radius: var(--radius); display: block; }
    .tags-section { margin-top: 24px; }
    .chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
    .chip { background: var(--surface-raised); padding: 4px 12px; border-radius: var(--radius-chip); display: flex; align-items: center; gap: 6px; }
    .chip button { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 1rem; }
    .tag-error { color: var(--danger); font-size: 0.85rem; margin-top: 6px; border-left: 3px solid var(--danger); padding-left: 10px; }

    /* Owner actions panel */
    .owner-actions {
      margin-top: 24px; padding: 20px;
      background: var(--surface); border-top: 1px solid var(--border); border-radius: var(--radius);
      display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    }
    .add-tag input { padding: 8px; background: var(--surface-raised); border: 1px solid var(--border); color: var(--text); border-radius: var(--radius); width: 200px; }
    .add-tag input:focus { outline: none; border-color: var(--border-focus); }
    .delete-btn { padding: 10px 24px; background: var(--danger); color: var(--danger-text); border: none; border-radius: var(--radius); cursor: pointer; margin-left: auto; }

    /* Copy URL */
    .copy-url-btn { padding: 8px 20px; background: var(--surface-raised); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; margin: 12px 0; transition: border-color var(--transition); }
    .copy-url-btn:hover { border-color: var(--border-focus); }

    /* Delete dialog */
    .dialog-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.7); display: flex; align-items: center; justify-content: center; z-index: 100; }
    .dialog { background: var(--surface); padding: 32px; border-radius: 10px; text-align: center; }
    .dialog button { margin: 12px 8px 0; padding: 8px 20px; border: none; border-radius: var(--radius); cursor: pointer; }
    .dialog button:first-of-type { background: var(--danger); color: var(--danger-text); }
    .dialog button:last-of-type { background: var(--surface-raised); color: var(--text); }
  `],
})
export class DetailComponent implements OnInit {
  image: ImageRecord | null = null;
  loading = true;
  error = false;
  newTagInput = '';
  tagError = '';
  showDeleteDialog = false;
  readonly skeletonChips = Array(4).fill(null);
  private currentId = '';

  constructor(
    public imageService: ImageService,
    public auth: AuthService,
    private route: ActivatedRoute,
    public router: Router,
    private cdr: ChangeDetectorRef,
    private toastService: ToastService,
  ) {}

  ngOnInit(): void {
    const id = this.route.snapshot.paramMap.get('id');
    if (!id) { this.loading = false; return; }
    this.currentId = id;
    this.fetchImage(id);
  }

  retry(): void {
    this.error = false;
    this.loading = true;
    this.cdr.markForCheck();
    this.fetchImage(this.currentId);
  }

  private fetchImage(id: string): void {
    this.imageService.get(id).subscribe({
      next: (img) => {
        this.image = img;
        this.loading = false;
        this.error = false;
        this.cdr.markForCheck();
      },
      error: (err) => {
        this.loading = false;
        if (err?.status === 404) {
          this.image = null;
          this.error = false;
        } else {
          this.error = true;
        }
        this.cdr.markForCheck();
      },
    });
  }

  removeTag(tag: string): void {
    if (!this.image) return;
    const updated = this.image.tags.filter((t) => t !== tag);
    this.imageService.updateTags(this.image.short_id, updated).subscribe({
      next: (img) => { this.image = img; this.tagError = ''; this.cdr.markForCheck(); },
      error: (err) => { this.tagError = err?.error?.detail ?? 'Failed to remove tag'; this.cdr.markForCheck(); },
    });
  }

  addTag(tag: string): void {
    if (!this.image || !tag.trim()) return;
    const normalised = tag.trim().toLowerCase();
    const updated = [...this.image.tags, normalised];
    this.imageService.updateTags(this.image.short_id, updated).subscribe({
      next: (img) => { this.image = img; this.newTagInput = ''; this.tagError = ''; this.cdr.markForCheck(); },
      error: (err) => { this.tagError = err?.error?.detail ?? 'Invalid tag'; this.cdr.markForCheck(); },
    });
  }

  onEnter(): void { this.addTag(this.newTagInput); }
  onBlur(): void { if (this.newTagInput.trim()) this.addTag(this.newTagInput); }

  confirmDelete(): void {
    if (!this.image) return;
    this.imageService.delete(this.image.short_id).subscribe({
      next: () => this.router.navigate(['/']),
      error: () => { this.showDeleteDialog = false; this.cdr.markForCheck(); },
    });
  }

  cancelDelete(): void {
    this.showDeleteDialog = false;
    this.cdr.markForCheck();
  }

  copyUrl(): void {
    if (!this.image) return;
    const url = this.image.file_url.startsWith('http')
      ? this.image.file_url
      : window.location.origin + this.image.file_url;
    navigator.clipboard.writeText(url)
      .then(() => this.toastService.show('URL copied!'))
      .catch(() => this.toastService.show('Failed to copy URL', 'error'));
  }

  goBack(): void { this.router.navigate(['/']); }

  onImgError(event: Event): void {
    const img = event.target as HTMLImageElement;
    if (!img.src.startsWith('data:')) {
      img.src = PLACEHOLDER_SVG;
    }
  }
}
