/**
 * @copyright 2026 NHCarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */

import { Component, OnInit, inject, signal, computed } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { ShowsService } from '../../services/shows.service';
import { AuthService } from '../../services/auth.service';
import { CommentsService } from '../../services/comments.service';
import { SanitizeService } from '../../services/sanitize.service';
import { SuggestionService } from '../../services/suggestion.service';
import { PaginationComponent } from '../shared/pagination.component';
import { LikeButtonComponent } from '../shared/like-button.component';
import { Show, ShowStatus, ShowType, CreateShowDto, UpdateShowDto, Comment, SuggestionEntity, Link } from '@library/shared-types';

@Component({
  selector: 'app-shows-list',
  standalone: true,
  imports: [CommonModule, RouterLink, FormsModule, PaginationComponent, LikeButtonComponent],
  template: `
    <div class="container">
      <div class="page-hero">
        <img src="/assets/avatars/shows-avatar.jpg" alt="Shows avatar" class="page-avatar" />
      </div>

      <div class="header-section">
        <h2>My Shows &amp; Films</h2>
        @if (authService.isAdmin()) {
          <button (click)="toggleAddForm()" class="btn btn-primary">
            {{ showAddForm() ? 'Cancel' : 'Add Show' }}
          </button>
        } @else if (authService.isAuthenticated() && !authService.user()?.isBanned) {
          <button (click)="toggleSuggestForm()" class="btn btn-primary">
            {{ showSuggestForm() ? 'Cancel' : 'Suggest a Show' }}
          </button>
        }
      </div>

      @if (showAddForm() && authService.isAdmin()) {
        <form (ngSubmit)="addShow()" class="add-form">
          <h3>Add New Show</h3>
          <div class="form-group">
            <label for="title">Title</label>
            <input
              type="text"
              id="title"
              [(ngModel)]="newShow.title"
              name="title"
              required
              placeholder="Enter show title"
            >
          </div>

          <div class="form-group">
            <label for="type">Type</label>
            <select id="type" [(ngModel)]="newShow.type" name="type" required>
              <option [value]="ShowType.tvSeries">TV Series</option>
              <option [value]="ShowType.anime">Anime</option>
              <option [value]="ShowType.film">Film</option>
              <option [value]="ShowType.documentary">Documentary</option>
            </select>
          </div>

          <div class="form-group">
            <label for="status">Status</label>
            <select id="status" [(ngModel)]="newShow.status" name="status" required>
              <option [value]="ShowStatus.watching">Currently Watching</option>
              <option [value]="ShowStatus.completed">Completed</option>
              <option [value]="ShowStatus.wantToWatch">Want to Watch</option>
              <option [value]="ShowStatus.retired">Retired</option>
            </select>
          </div>

          <div class="form-group">
            <label for="dateStarted">Date Started</label>
            <input
              type="date"
              id="dateStarted"
              [(ngModel)]="newShow.dateStarted"
              name="dateStarted"
            >
          </div>

          <div class="form-group">
            <label for="dateFinished">Date Finished</label>
            <input
              type="date"
              id="dateFinished"
              [(ngModel)]="newShow.dateFinished"
              name="dateFinished"
            >
          </div>

          <div class="form-group">
            <label for="rating">Rating (1-10)</label>
            <input
              type="number"
              id="rating"
              [(ngModel)]="newShow.rating"
              name="rating"
              min="1"
              max="10"
            >
          </div>

          <div class="form-row">
            <div class="form-group">
              <label for="timeHours">Time Spent (Hours)</label>
              <input
                type="number"
                id="timeHours"
                [(ngModel)]="newShowTimeHours"
                name="timeHours"
                min="0"
                placeholder="0"
                (ngModelChange)="updateNewShowTimeSpent()"
              >
            </div>
            <div class="form-group">
              <label for="timeMinutes">Time Spent (Minutes)</label>
              <input
                type="number"
                id="timeMinutes"
                [(ngModel)]="newShowTimeMinutes"
                name="timeMinutes"
                min="0"
                max="59"
                placeholder="0"
                (ngModelChange)="updateNewShowTimeSpent()"
              >
            </div>
          </div>

          <div class="form-group">
            <label for="notes">Notes</label>
            <textarea
              id="notes"
              [(ngModel)]="newShow.notes"
              name="notes"
              rows="3"
              placeholder="Any thoughts about the show..."
            ></textarea>
          </div>

          <div class="form-group">
            <label for="coverImage">Poster/Cover Art (max 500KB)</label>
            <input
              type="file"
              id="coverImage"
              name="coverImage"
              accept="image/*"
              (change)="onImageSelected($event, 'new')"
            >
            @if (newShowImagePreview()) {
              <div class="image-preview">
                <img [src]="newShowImagePreview()" alt="Cover preview">
                <button type="button" (click)="clearImage('new')" class="btn btn-danger btn-sm">Remove</button>
              </div>
            }
            @if (imageError()) {
              <span class="error-text">{{ imageError() }}</span>
            }
          </div>

          <div class="form-group">
            <div class="tags-input-container" aria-label="Tags">
              @for (tag of newShow.tags; track tag; let i = $index) {
                <span class="tag">
                  {{ tag }}
                  <button type="button" (click)="removeTag(i, 'new')" class="tag-remove">×</button>
                </span>
              }
              <input
                type="text"
                [(ngModel)]="newTagInput"
                name="newTagInput"
                placeholder="Add a tag and press Enter"
                (keydown.enter)="addTag('new'); $event.preventDefault()"
              >
            </div>
          </div>

          <div class="form-group" aria-label="External Links">
            <div class="links-list">
              @for (link of newShow.links; track link.url; let i = $index) {
                <div class="link-item">
                  <span>{{ link.title }}: {{ link.url }}</span>
                  <button type="button" (click)="removeLink(i, 'new')" class="btn btn-danger btn-sm">×</button>
                </div>
              }
            </div>
            <div class="link-add-form">
              <input
                type="text"
                [(ngModel)]="newLinkTitle"
                name="newLinkTitle"
                placeholder="Link title (e.g., IMDB)"
              >
              <input
                type="url"
                [(ngModel)]="newLinkUrl"
                name="newLinkUrl"
                placeholder="https://..."
              >
              <button type="button" (click)="addLink('new')" class="btn btn-secondary btn-sm">Add Link</button>
            </div>
          </div>

          <div class="form-actions">
            <button type="submit" class="btn btn-primary">Add Show</button>
            <button type="button" (click)="toggleAddForm()" class="btn btn-secondary">Cancel</button>
          </div>
        </form>
      }

      @if (editingShow() && authService.isAdmin()) {
        <form (ngSubmit)="saveEdit()" class="add-form">
          <h3>Edit Show</h3>
          <div class="form-group">
            <label for="edit-title">Title</label>
            <input
              type="text"
              id="edit-title"
              [(ngModel)]="editShow.title"
              name="title"
              required
              placeholder="Enter show title"
            >
          </div>

          <div class="form-group">
            <label for="edit-type">Type</label>
            <select id="edit-type" [(ngModel)]="editShow.type" name="type" required>
              <option [value]="ShowType.tvSeries">TV Series</option>
              <option [value]="ShowType.anime">Anime</option>
              <option [value]="ShowType.film">Film</option>
              <option [value]="ShowType.documentary">Documentary</option>
            </select>
          </div>

          <div class="form-group">
            <label for="edit-status">Status</label>
            <select id="edit-status" [(ngModel)]="editShow.status" name="status" required>
              <option [value]="ShowStatus.watching">Currently Watching</option>
              <option [value]="ShowStatus.completed">Completed</option>
              <option [value]="ShowStatus.wantToWatch">Want to Watch</option>
              <option [value]="ShowStatus.retired">Retired</option>
            </select>
          </div>

          <div class="form-group">
            <label for="edit-dateStarted">Date Started</label>
            <input
              type="date"
              id="edit-dateStarted"
              [(ngModel)]="editShow.dateStarted"
              name="dateStarted"
            >
          </div>

          <div class="form-group">
            <label for="edit-dateFinished">Date Finished</label>
            <input
              type="date"
              id="edit-dateFinished"
              [(ngModel)]="editShow.dateFinished"
              name="dateFinished"
            >
          </div>

          <div class="form-group">
            <label for="edit-rating">Rating (1-10)</label>
            <input
              type="number"
              id="edit-rating"
              [(ngModel)]="editShow.rating"
              name="rating"
              min="1"
              max="10"
            >
          </div>

          <div class="form-row">
            <div class="form-group">
              <label for="edit-timeHours">Time Spent (Hours)</label>
              <input
                type="number"
                id="edit-timeHours"
                [(ngModel)]="editShowTimeHours"
                name="timeHours"
                min="0"
                placeholder="0"
                (ngModelChange)="updateEditShowTimeSpent()"
              >
            </div>
            <div class="form-group">
              <label for="edit-timeMinutes">Time Spent (Minutes)</label>
              <input
                type="number"
                id="edit-timeMinutes"
                [(ngModel)]="editShowTimeMinutes"
                name="timeMinutes"
                min="0"
                max="59"
                placeholder="0"
                (ngModelChange)="updateEditShowTimeSpent()"
              >
            </div>
          </div>

          <div class="form-group">
            <label for="edit-notes">Notes</label>
            <textarea
              id="edit-notes"
              [(ngModel)]="editShow.notes"
              name="notes"
              rows="3"
              placeholder="Any thoughts about the show..."
            ></textarea>
          </div>

          <div class="form-group">
            <label for="edit-coverImage">Poster/Cover Art (max 500KB)</label>
            <input
              type="file"
              id="edit-coverImage"
              name="coverImage"
              accept="image/*"
              (change)="onImageSelected($event, 'edit')"
            >
            @if (editShowImagePreview()) {
              <div class="image-preview">
                <img [src]="editShowImagePreview()" alt="Cover preview">
                <button type="button" (click)="clearImage('edit')" class="btn btn-danger btn-sm">Remove</button>
              </div>
            }
            @if (imageError()) {
              <span class="error-text">{{ imageError() }}</span>
            }
          </div>

          <div class="form-group">
            <div class="tags-input-container" aria-label="Tags">
              @for (tag of editShow.tags; track tag; let i = $index) {
                <span class="tag">
                  {{ tag }}
                  <button type="button" (click)="removeTag(i, 'edit')" class="tag-remove">×</button>
                </span>
              }
              <input
                type="text"
                [(ngModel)]="editTagInput"
                name="editTagInput"
                placeholder="Add a tag and press Enter"
                (keydown.enter)="addTag('edit'); $event.preventDefault()"
              >
            </div>
          </div>

          <div class="form-group" aria-label="External Links">
            <div class="links-list">
              @for (link of editShow.links; track link.url; let i = $index) {
                <div class="link-item">
                  <span>{{ link.title }}: {{ link.url }}</span>
                  <button type="button" (click)="removeLink(i, 'edit')" class="btn btn-danger btn-sm">×</button>
                </div>
              }
            </div>
            <div class="link-add-form">
              <input
                type="text"
                [(ngModel)]="editLinkTitle"
                name="editLinkTitle"
                placeholder="Link title (e.g., IMDB)"
              >
              <input
                type="url"
                [(ngModel)]="editLinkUrl"
                name="editLinkUrl"
                placeholder="https://..."
              >
              <button type="button" (click)="addLink('edit')" class="btn btn-secondary btn-sm">Add Link</button>
            </div>
          </div>

          <div class="form-actions">
            <button type="submit" class="btn btn-primary">Save Changes</button>
            <button type="button" (click)="cancelEdit()" class="btn btn-secondary">Cancel</button>
          </div>
        </form>
      }

      @if (showSuggestForm() && !authService.isAdmin() && authService.isAuthenticated()) {
        <form (ngSubmit)="submitSuggestion()" class="add-form suggest-form">
          <h3>Suggest a Show</h3>
          <p class="suggest-note">Your suggestion will be reviewed by Naomi. If accepted, it will be added to the watch list!</p>
          <div class="form-group">
            <label for="suggest-title">Title</label>
            <input
              type="text"
              id="suggest-title"
              [(ngModel)]="suggestedShow.title"
              name="title"
              required
              placeholder="Enter show title"
            >
          </div>

          <div class="form-group">
            <label for="suggest-type">Type</label>
            <select id="suggest-type" [(ngModel)]="suggestedShow.type" name="type" required>
              <option [value]="ShowType.tvSeries">TV Series</option>
              <option [value]="ShowType.anime">Anime</option>
              <option [value]="ShowType.film">Film</option>
              <option [value]="ShowType.documentary">Documentary</option>
            </select>
          </div>

          <div class="form-group">
            <label for="suggest-notes">Notes (why should Naomi watch this?)</label>
            <textarea
              id="suggest-notes"
              [(ngModel)]="suggestedShow.notes"
              name="notes"
              rows="3"
              placeholder="Tell Naomi why this show is worth watching..."
            ></textarea>
          </div>

          <div class="form-group">
            <label for="suggest-coverImage">Poster/Cover Art (max 500KB)</label>
            <input
              type="file"
              id="suggest-coverImage"
              name="coverImage"
              accept="image/*"
              (change)="onImageSelected($event, 'suggest')"
            >
            @if (suggestShowImagePreview()) {
              <div class="image-preview">
                <img [src]="suggestShowImagePreview()" alt="Cover preview">
                <button type="button" (click)="clearImage('suggest')" class="btn btn-danger btn-sm">Remove</button>
              </div>
            }
            @if (imageError()) {
              <span class="error-text">{{ imageError() }}</span>
            }
          </div>

          <div class="form-actions">
            <button type="submit" class="btn btn-primary">Submit Suggestion</button>
            <button type="button" (click)="toggleSuggestForm()" class="btn btn-secondary">Cancel</button>
          </div>
        </form>
      }

      <div class="search-section">
        <input
          type="text"
          [value]="searchQuery()"
          (input)="searchQuery.set($any($event.target).value); currentPage.set(1)"
          name="search"
          placeholder="Search by title, type, or notes..."
          class="search-input"
        >
        <button (click)="toggleFilters()" class="btn btn-secondary btn-sm">
          {{ showFilters() ? 'Hide' : 'Show' }} Advanced Filters
          @if (selectedTags().length > 0) {
            ({{ selectedTags().length }})
          }
        </button>
        @if (searchQuery() || selectedTags().length > 0) {
          <button (click)="clearFilters()" class="btn btn-secondary btn-sm">
            Clear All Filters
          </button>
        }
      </div>

      @if (showFilters()) {
        <div class="advanced-filters">
          <div class="filter-group">
            <h4>Filter by Tags</h4>
            <div class="tags-filter">
              @for (tag of allTags(); track tag) {
                <label class="tag-checkbox">
                  <input
                    type="checkbox"
                    [checked]="selectedTags().includes(tag)"
                    (change)="toggleTag(tag)"
                  >
                  <span>{{ tag }}</span>
                </label>
              }
              @empty {
                <p class="no-tags">No tags available</p>
              }
            </div>
          </div>
        </div>
      }

      <div class="filters">
        <button
          (click)="setFilter('all')"
          [class.active]="statusFilter() === 'all'"
          class="filter-btn"
        >
          All ({{ shows().length }})
        </button>
        <button
          (click)="setFilter(ShowStatus.watching)"
          [class.active]="statusFilter() === ShowStatus.watching"
          class="filter-btn"
        >
          Watching ({{ watchingCount() }})
        </button>
        <button
          (click)="setFilter(ShowStatus.completed)"
          [class.active]="statusFilter() === ShowStatus.completed"
          class="filter-btn"
        >
          Completed ({{ completedCount() }})
        </button>
        <button
          (click)="setFilter(ShowStatus.wantToWatch)"
          [class.active]="statusFilter() === ShowStatus.wantToWatch"
          class="filter-btn"
        >
          Want to Watch ({{ wantToWatchCount() }})
        </button>
        <button
          (click)="setFilter(ShowStatus.retired)"
          [class.active]="statusFilter() === ShowStatus.retired"
          class="filter-btn"
        >
          Retired ({{ retiredCount() }})
        </button>
      </div>

      @if (loading()) {
        <div class="loading">Loading shows...</div>
      } @else if (filteredShows().length === 0) {
        <div class="empty-state">
          <p>No shows found in this category.</p>
        </div>
      } @else {
        <app-pagination
          [currentPage]="currentPage()"
          [pageSize]="pageSize()"
          [totalItems]="totalFilteredShows()"
          (pageChange)="onPageChange($event)"
          (pageSizeChange)="onPageSizeChange($event)"
        ></app-pagination>

        <div class="shows-grid">
          @for (show of paginatedShows(); track show.id) {
            <div class="show-card" [class.completed]="show.status === ShowStatus.completed">
              <a [routerLink]="['/shows', show.id]" class="card-link">
                <img [src]="show.coverImage || '/assets/default-cover.jpg'" [alt]="show.title" class="show-cover">

                <div class="show-info">
                  <h3>{{ show.title }}</h3>
                  @if (show.type) {
                    <p class="type">{{ getTypeLabel(show.type) }}</p>
                  }
                  <span class="status status-{{ show.status }}">
                    {{ getStatusLabel(show.status) }}
                  </span>

                  @if (show.rating) {
                    <div class="rating">
                      @for (star of [1,2,3,4,5,6,7,8,9,10]; track star) {
                        <span [class.filled]="star <= show.rating!">★</span>
                      }
                    </div>
                  }
                </div>
              </a>

              <div class="card-actions">
                <app-like-button
                  entityType="show"
                  [entityId]="show.id"
                ></app-like-button>

                @if (authService.isAdmin()) {
                  <div class="admin-actions">
                    <button (click)="startEdit(show)" class="btn btn-secondary btn-sm">
                      Edit
                    </button>
                    <button (click)="deleteShow(show)" class="btn btn-danger btn-sm">
                      Delete
                    </button>
                  </div>
                }
              </div>
            </div>
          }
        </div>

        <app-pagination
          [currentPage]="currentPage()"
          [pageSize]="pageSize()"
          [totalItems]="totalFilteredShows()"
          (pageChange)="onPageChange($event)"
          (pageSizeChange)="onPageSizeChange($event)"
        ></app-pagination>
      }
    </div>
  `,
  styles: [`
    .container {
      max-width: 1200px;
      margin: 0 auto;
      padding: 2rem;
    }

    .page-hero {
      text-align: center;
      margin-bottom: 2rem;
    }

    .page-avatar {
      width: 120px;
      height: 120px;
      border-radius: 50%;
      object-fit: cover;
      border: 3px solid #e84393;
      box-shadow: 0 4px 12px rgba(232, 67, 147, 0.3);
      transition: all 0.3s;
    }

    .page-avatar:hover {
      transform: scale(1.05);
      box-shadow: 0 8px 16px rgba(232, 67, 147, 0.5);
    }

    .header-section {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 2rem;
    }

    h2 {
      margin: 0;
    }

    .add-form {
      background: #f8f9fa;
      padding: 1.5rem;
      border-radius: 8px;
      margin-bottom: 2rem;
    }

    .suggest-form {
      border: 2px solid #e84393;
      background: #fff5f9;
    }

    .suggest-note {
      color: #666;
      font-size: 0.9rem;
      margin-bottom: 1rem;
      font-style: italic;
    }

    .form-group {
      margin-bottom: 1rem;
    }

    .form-group label {
      display: block;
      margin-bottom: 0.5rem;
      font-weight: 500;
    }

    .form-group input,
    .form-group select,
    .form-group textarea {
      width: 100%;
      padding: 0.5rem;
      border: 1px solid #ddd;
      border-radius: 4px;
      font-size: 1rem;
    }

    .form-row {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 1rem;
      margin-bottom: 1rem;
    }

    .form-actions {
      display: flex;
      gap: 1rem;
      margin-top: 1rem;
    }

    .search-section {
      display: flex;
      gap: 1rem;
      align-items: center;
      margin-bottom: 1rem;
      flex-wrap: wrap;
    }

    .search-input {
      flex: 1;
      min-width: 250px;
      padding: 0.5rem 1rem;
      border: 1px solid #ddd;
      border-radius: 4px;
      font-size: 1rem;
    }

    .search-input:focus {
      outline: none;
      border-color: #e84393;
    }

    .advanced-filters {
      background: #f8f9fa;
      padding: 1rem;
      border-radius: 8px;
      margin-bottom: 1rem;
    }

    .filter-group h4 {
      margin: 0 0 0.75rem 0;
      color: #374151;
      font-size: 0.95rem;
      font-weight: 600;
    }

    .tags-filter {
      display: flex;
      flex-wrap: wrap;
      gap: 0.75rem;
    }

    .tag-checkbox {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      cursor: pointer;
      padding: 0.25rem 0.75rem;
      border: 1px solid #e5e7eb;
      border-radius: 20px;
      background: white;
      transition: all 0.2s;
    }

    .tag-checkbox:hover {
      border-color: #e84393;
      background: #fff5f9;
    }

    .tag-checkbox input[type="checkbox"] {
      width: 16px;
      height: 16px;
      cursor: pointer;
    }

    .tag-checkbox span {
      font-size: 0.875rem;
      color: #374151;
    }

    .no-tags {
      color: #6b7280;
      font-style: italic;
      font-size: 0.875rem;
    }

    .filters {
      display: flex;
      gap: 1rem;
      margin-bottom: 2rem;
      flex-wrap: wrap;
    }

    .filter-btn {
      padding: 0.5rem 1rem;
      background: #e5e7eb;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      transition: all 0.3s;
    }

    .filter-btn:hover {
      background: #d1d5db;
    }

    .filter-btn.active {
      background: #e84393;
      color: white;
    }

    .loading {
      text-align: center;
      padding: 2rem;
      color: #666;
    }

    .empty-state {
      text-align: center;
      padding: 3rem;
      color: #666;
    }

    .shows-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
      gap: 1.5rem;
    }

    .show-card {
      background: white;
      border: 1px solid #e5e7eb;
      border-radius: 8px;
      overflow: hidden;
      transition: transform 0.3s, box-shadow 0.3s;
      display: flex;
      flex-direction: column;
    }

    .show-card:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    }

    .show-card.completed {
      opacity: 0.8;
    }

    .card-link {
      display: block;
      text-decoration: none;
      color: inherit;
      flex: 1;
    }

    .card-link:hover h3 {
      color: #e84393;
    }

    .show-cover {
      width: 100%;
      height: 200px;
      object-fit: cover;
    }

    .show-info {
      padding: 1rem;
    }

    .show-info h3 {
      margin: 0 0 0.5rem 0;
      font-size: 1.1rem;
      transition: color 0.2s;
    }

    .type {
      color: #666;
      font-size: 0.9rem;
      margin: 0.5rem 0;
    }

    .status {
      display: inline-block;
      padding: 0.25rem 0.5rem;
      border-radius: 4px;
      font-size: 0.8rem;
      font-weight: 500;
    }

    .status-WATCHING { background: #fef3c7; color: #92400e; }
    .status-COMPLETED { background: #d1fae5; color: #065f46; }
    .status-WANT_TO_WATCH { background: #e0e7ff; color: #3730a3; }
    .status-RETIRED { background: #fecaca; color: #991b1b; }

    .rating {
      margin: 0.5rem 0;
    }

    .rating span {
      color: #e5e7eb;
      font-size: 1rem;
    }

    .rating span.filled {
      color: #8b5cf6;
    }

    .card-actions {
      padding: 1rem;
      padding-top: 0;
      border-top: 1px solid #e5e7eb;
      display: flex;
      flex-direction: column;
      gap: 0.75rem;
    }

    .admin-actions {
      display: flex;
      gap: 0.5rem;
    }

    .btn {
      padding: 0.5rem 1rem;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 0.9rem;
      transition: opacity 0.3s;
    }

    .btn:hover {
      opacity: 0.8;
    }

    .btn-primary { background: #e84393; color: white; }
    .btn-secondary { background: #6b7280; color: white; }
    .btn-danger { background: #ef4444; color: white; }
    .btn-sm { padding: 0.25rem 0.75rem; font-size: 0.85rem; }
    .btn-xs { padding: 0.15rem 0.5rem; font-size: 0.75rem; }

    .image-preview {
      margin-top: 0.5rem;
      display: flex;
      align-items: center;
      gap: 1rem;
    }

    .image-preview img {
      max-width: 100px;
      max-height: 150px;
      border-radius: 4px;
      border: 2px solid #e5e7eb;
    }

    .error-text {
      color: #ef4444;
      font-size: 0.875rem;
      display: block;
      margin-top: 0.25rem;
    }

    input[type="file"] {
      padding: 0.5rem;
      border: 2px dashed #e5e7eb;
      border-radius: 4px;
      background: #f9fafb;
      cursor: pointer;
    }

    input[type="file"]:hover {
      border-color: #8b5cf6;
    }

    .tags-input-container {
      display: flex;
      flex-wrap: wrap;
      gap: 0.5rem;
      padding: 0.5rem;
      border: 1px solid #ddd;
      border-radius: 4px;
      background: #f9fafb;
    }

    .tags-input-container input {
      flex: 1;
      min-width: 150px;
      border: none;
      padding: 0.25rem;
      font-size: 0.9rem;
      background: transparent;
    }

    .tags-input-container input:focus {
      outline: none;
    }

    .tag {
      display: inline-flex;
      align-items: center;
      gap: 0.25rem;
      background: #e84393;
      color: white;
      padding: 0.25rem 0.5rem;
      border-radius: 4px;
      font-size: 0.85rem;
    }

    .tag-remove {
      background: none;
      border: none;
      color: white;
      cursor: pointer;
      padding: 0;
      font-size: 1rem;
      line-height: 1;
    }

    .tag-remove:hover {
      opacity: 0.8;
    }

    .tag-chip {
      background: rgba(232, 67, 147, 0.2);
      color: #e84393;
      padding: 0.2rem 0.5rem;
      border-radius: 4px;
      font-size: 0.8rem;
    }

    .links-list {
      margin-bottom: 0.5rem;
    }

    .link-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0.5rem;
      background: #f9fafb;
      border-radius: 4px;
      margin-bottom: 0.25rem;
    }

    .link-add-form {
      display: flex;
      gap: 0.5rem;
      flex-wrap: wrap;
    }

    .link-add-form input {
      flex: 1;
      min-width: 120px;
    }
  `]
})
export class ShowsListComponent implements OnInit {
  showsService = inject(ShowsService);
  authService = inject(AuthService);
  commentsService = inject(CommentsService);
  sanitizeService = inject(SanitizeService);
  suggestionService = inject(SuggestionService);

  shows = signal<Show[]>([]);
  loading = signal(true);
  showAddForm = signal(false);
  editingShow = signal<Show | null>(null);
  statusFilter = signal<'all' | ShowStatus>('all');

  // Pagination state
  currentPage = signal(1);
  pageSize = signal(25);

  // Search and filter state
  searchQuery = signal('');
  selectedTags = signal<string[]>([]);
  showFilters = signal(false);

  comments = signal<Record<string, Comment[]>>({});
  commentsLoading = signal<Record<string, boolean>>({});
  expandedComments = signal<Record<string, boolean>>({});
  newCommentContent: Record<string, string> = {};
  editingCommentId = signal<string | null>(null);
  editCommentContent = '';

  newShowImagePreview = signal<string | null>(null);
  editShowImagePreview = signal<string | null>(null);
  suggestShowImagePreview = signal<string | null>(null);
  imageError = signal<string | null>(null);
  private readonly MAX_IMAGE_SIZE = 500 * 1024;

  // Suggestion state
  showSuggestForm = signal(false);
  suggestedShow: { title: string; type: ShowType; notes?: string; coverImage?: string } = {
    title: '',
    type: ShowType.tvSeries,
    notes: '',
    coverImage: undefined
  };

  ShowStatus = ShowStatus;
  ShowType = ShowType;

  watchingCount = computed(() => this.shows().filter(show => show.status === ShowStatus.watching).length);
  completedCount = computed(() => this.shows().filter(show => show.status === ShowStatus.completed).length);
  wantToWatchCount = computed(() => this.shows().filter(show => show.status === ShowStatus.wantToWatch).length);
  retiredCount = computed(() => this.shows().filter(show => show.status === ShowStatus.retired).length);

  allTags = computed(() => {
    const tagsSet = new Set<string>();
    this.shows().forEach(show => {
      show.tags?.forEach(tag => tagsSet.add(tag));
    });
    return Array.from(tagsSet).sort();
  });

  filteredShows = computed(() => {
    let shows = this.shows();

    // Apply status filter
    const statusFilter = this.statusFilter();
    if (statusFilter !== 'all') {
      shows = shows.filter(show => show.status === statusFilter);
    }

    // Apply search filter
    const searchQuery = this.searchQuery().toLowerCase().trim();
    if (searchQuery) {
      shows = shows.filter(show =>
        show.title.toLowerCase().includes(searchQuery) ||
        show.notes?.toLowerCase().includes(searchQuery) ||
        this.getTypeLabel(show.type).toLowerCase().includes(searchQuery)
      );
    }

    // Apply tag filter
    const selectedTags = this.selectedTags();
    if (selectedTags.length > 0) {
      shows = shows.filter(show =>
        selectedTags.every(tag => show.tags?.includes(tag))
      );
    }

    return shows;
  });

  paginatedShows = computed(() => {
    const shows = this.filteredShows();
    const start = (this.currentPage() - 1) * this.pageSize();
    const end = start + this.pageSize();
    return shows.slice(start, end);
  });

  totalFilteredShows = computed(() => this.filteredShows().length);

  newShow: Partial<CreateShowDto> & { dateStarted?: Date; dateFinished?: Date } = {
    title: '',
    type: ShowType.tvSeries,
    status: ShowStatus.wantToWatch,
    rating: undefined,
    notes: '',
    dateStarted: undefined,
    dateFinished: undefined,
    tags: [],
    links: []
  };

  editShow: Partial<UpdateShowDto> = {};

  // Time tracking state
  newShowTimeHours = 0;
  newShowTimeMinutes = 0;
  editShowTimeHours = 0;
  editShowTimeMinutes = 0;

  // Tags and links input state
  newTagInput = '';
  editTagInput = '';
  newLinkTitle = '';
  newLinkUrl = '';
  editLinkTitle = '';
  editLinkUrl = '';

  ngOnInit() {
    this.loadShows();
  }

  loadShows() {
    this.loading.set(true);
    this.showsService.getAllShows().subscribe({
      next: (shows) => {
        this.shows.set(shows);
        this.loading.set(false);
      },
      error: () => {
        this.loading.set(false);
      }
    });
  }

  setFilter(filter: 'all' | ShowStatus) {
    this.statusFilter.set(filter);
    this.currentPage.set(1); // Reset to first page when filter changes
  }

  toggleTag(tag: string) {
    const current = this.selectedTags();
    if (current.includes(tag)) {
      this.selectedTags.set(current.filter(t => t !== tag));
    } else {
      this.selectedTags.set([...current, tag]);
    }
    this.currentPage.set(1); // Reset to first page when tags change
  }

  clearFilters() {
    this.searchQuery.set('');
    this.selectedTags.set([]);
    this.statusFilter.set('all');
    this.currentPage.set(1);
  }

  toggleFilters() {
    this.showFilters.update(v => !v);
  }

  onPageChange(page: number) {
    this.currentPage.set(page);
  }

  onPageSizeChange(pageSize: number) {
    this.pageSize.set(pageSize);
    // Calculate new current page to stay on approximately the same content
    const firstItemIndex = (this.currentPage() - 1) * this.pageSize();
    const newPage = Math.floor(firstItemIndex / pageSize) + 1;
    this.currentPage.set(newPage);
  }

  getStatusLabel(status: ShowStatus): string {
    switch (status) {
      case ShowStatus.watching: return 'Currently Watching';
      case ShowStatus.completed: return 'Completed';
      case ShowStatus.wantToWatch: return 'Want to Watch';
      case ShowStatus.retired: return 'Retired';
    }
  }

  getTypeLabel(type: ShowType): string {
    switch (type) {
      case ShowType.tvSeries: return 'TV Series';
      case ShowType.anime: return 'Anime';
      case ShowType.film: return 'Film';
      case ShowType.documentary: return 'Documentary';
    }
  }

  toggleAddForm() {
    this.showAddForm.update(v => !v);
    if (!this.showAddForm()) {
      this.resetForm();
    }
  }

  resetForm() {
    this.newShow = {
      title: '',
      type: ShowType.tvSeries,
      status: ShowStatus.wantToWatch,
      rating: undefined,
      notes: '',
      coverImage: undefined,
      dateStarted: undefined,
      dateFinished: undefined,
      tags: [],
      links: []
    };
    this.newShowTimeHours = 0;
    this.newShowTimeMinutes = 0;
    this.newShowImagePreview.set(null);
    this.imageError.set(null);
    this.newTagInput = '';
    this.newLinkTitle = '';
    this.newLinkUrl = '';
  }

  updateNewShowTimeSpent() {
    const totalMinutes = (this.newShowTimeHours * 60) + this.newShowTimeMinutes;
    this.newShow.timeSpent = totalMinutes > 0 ? totalMinutes : undefined;
  }

  updateEditShowTimeSpent() {
    const totalMinutes = (this.editShowTimeHours * 60) + this.editShowTimeMinutes;
    this.editShow.timeSpent = totalMinutes > 0 ? totalMinutes : undefined;
  }

  addTag(target: 'new' | 'edit') {
    const input = target === 'new' ? this.newTagInput.trim() : this.editTagInput.trim();
    if (!input) return;

    if (target === 'new') {
      this.newShow.tags = [...(this.newShow.tags || []), input];
      this.newTagInput = '';
    } else {
      this.editShow.tags = [...(this.editShow.tags || []), input];
      this.editTagInput = '';
    }
  }

  removeTag(index: number, target: 'new' | 'edit') {
    if (target === 'new') {
      this.newShow.tags = (this.newShow.tags || []).filter((_, i) => i !== index);
    } else {
      this.editShow.tags = (this.editShow.tags || []).filter((_, i) => i !== index);
    }
  }

  addLink(target: 'new' | 'edit') {
    const title = target === 'new' ? this.newLinkTitle.trim() : this.editLinkTitle.trim();
    const url = target === 'new' ? this.newLinkUrl.trim() : this.editLinkUrl.trim();
    if (!title || !url) return;

    if (target === 'new') {
      this.newShow.links = [...(this.newShow.links || []), { title, url }];
      this.newLinkTitle = '';
      this.newLinkUrl = '';
    } else {
      this.editShow.links = [...(this.editShow.links || []), { title, url }];
      this.editLinkTitle = '';
      this.editLinkUrl = '';
    }
  }

  removeLink(index: number, target: 'new' | 'edit') {
    if (target === 'new') {
      this.newShow.links = (this.newShow.links || []).filter((_, i) => i !== index);
    } else {
      this.editShow.links = (this.editShow.links || []).filter((_, i) => i !== index);
    }
  }

  addShow() {
    if (!this.newShow.title || !this.newShow.type || !this.newShow.status) return;

    const showToAdd: CreateShowDto = {
      title: this.newShow.title,
      type: this.newShow.type,
      status: this.newShow.status,
      dateStarted: this.newShow.dateStarted ? new Date(this.newShow.dateStarted) : undefined,
      dateFinished: this.newShow.dateFinished ? new Date(this.newShow.dateFinished) : undefined,
      rating: this.newShow.rating,
      notes: this.newShow.notes,
      coverImage: this.newShow.coverImage,
      tags: this.newShow.tags || [],
      links: this.newShow.links || []
    };

    this.showsService.createShow(showToAdd).subscribe(() => {
      this.loadShows();
      this.toggleAddForm();
    });
  }

  deleteShow(show: Show) {
    if (confirm(`Are you sure you want to delete "${show.title}"?`)) {
      this.showsService.deleteShow(show.id).subscribe(() => {
        this.loadShows();
      });
    }
  }

  startEdit(show: Show) {
    this.editingShow.set(show);
    this.editShow = {
      title: show.title,
      type: show.type,
      status: show.status,
      dateStarted: show.dateStarted,
      dateFinished: show.dateFinished,
      rating: show.rating,
      notes: show.notes,
      coverImage: show.coverImage,
      tags: [...(show.tags || [])],
      links: [...(show.links || [])],
      timeSpent: show.timeSpent
    };
    // Populate time fields from existing timeSpent
    if (show.timeSpent) {
      this.editShowTimeHours = Math.floor(show.timeSpent / 60);
      this.editShowTimeMinutes = show.timeSpent % 60;
    } else {
      this.editShowTimeHours = 0;
      this.editShowTimeMinutes = 0;
    }
    this.editShowImagePreview.set(show.coverImage || null);
    this.showAddForm.set(false);
    this.imageError.set(null);
    this.editTagInput = '';
    this.editLinkTitle = '';
    this.editLinkUrl = '';

    // Scroll to top so the form is visible
    window.scrollTo({ top: 0, behavior: 'smooth' });
  }

  cancelEdit() {
    this.editingShow.set(null);
    this.editShow = {};
    this.editShowImagePreview.set(null);
    this.imageError.set(null);
    this.editTagInput = '';
    this.editLinkTitle = '';
    this.editLinkUrl = '';
  }

  saveEdit() {
    const show = this.editingShow();
    if (!show || !this.editShow.title || !this.editShow.type || !this.editShow.status) return;

    const updateData = {
      ...this.editShow,
      dateStarted: this.editShow.dateStarted ? new Date(this.editShow.dateStarted) : undefined,
      dateFinished: this.editShow.dateFinished ? new Date(this.editShow.dateFinished) : undefined,
    };

    this.showsService.updateShow(show.id, updateData).subscribe(() => {
      this.loadShows();
      this.cancelEdit();
    });
  }

  onImageSelected(event: Event, target: 'new' | 'edit' | 'suggest') {
    const input = event.target as HTMLInputElement;
    const file = input.files?.[0];

    if (!file) return;

    this.imageError.set(null);

    if (file.size > this.MAX_IMAGE_SIZE) {
      this.imageError.set(`Image too large. Maximum size is ${this.MAX_IMAGE_SIZE / 1024}KB.`);
      input.value = '';
      return;
    }

    if (!file.type.startsWith('image/')) {
      this.imageError.set('Please select an image file.');
      input.value = '';
      return;
    }

    const reader = new FileReader();
    reader.onload = () => {
      const base64 = reader.result as string;
      if (target === 'new') {
        this.newShowImagePreview.set(base64);
        this.newShow.coverImage = base64;
      } else if (target === 'edit') {
        this.editShowImagePreview.set(base64);
        this.editShow.coverImage = base64;
      } else {
        this.suggestShowImagePreview.set(base64);
        this.suggestedShow.coverImage = base64;
      }
    };
    reader.readAsDataURL(file);
  }

  clearImage(target: 'new' | 'edit' | 'suggest') {
    if (target === 'new') {
      this.newShowImagePreview.set(null);
      this.newShow.coverImage = undefined;
    } else if (target === 'edit') {
      this.editShowImagePreview.set(null);
      this.editShow.coverImage = undefined;
    } else {
      this.suggestShowImagePreview.set(null);
      this.suggestedShow.coverImage = undefined;
    }
    this.imageError.set(null);
  }

  formatDate(date: Date | string): string {
    return new Date(date).toLocaleDateString();
  }

  formatTimeSpent(minutes: number): string {
    const hours = Math.floor(minutes / 60);
    const mins = minutes % 60;

    if (hours === 0) {
      return `${mins}m`;
    } else if (mins === 0) {
      return `${hours}h`;
    } else {
      return `${hours}h ${mins}m`;
    }
  }

  toggleComments(showId: string) {
    const expanded = this.expandedComments();
    const isCurrentlyExpanded = expanded[showId];

    this.expandedComments.set({
      ...expanded,
      [showId]: !isCurrentlyExpanded
    });

    if (!isCurrentlyExpanded && !this.comments()[showId]) {
      this.loadComments(showId);
    }
  }

  loadComments(showId: string) {
    this.commentsLoading.set({
      ...this.commentsLoading(),
      [showId]: true
    });

    this.commentsService.getCommentsForShow(showId).subscribe({
      next: (comments) => {
        this.comments.set({
          ...this.comments(),
          [showId]: comments
        });
        this.commentsLoading.set({
          ...this.commentsLoading(),
          [showId]: false
        });
      },
      error: () => {
        this.commentsLoading.set({
          ...this.commentsLoading(),
          [showId]: false
        });
      }
    });
  }

  getCommentCount(showId: string): number {
    return this.comments()[showId]?.length || 0;
  }

  addComment(showId: string) {
    const content = this.newCommentContent[showId];
    if (!content?.trim()) return;

    this.commentsService.addCommentToShow(showId, { content }).subscribe({
      next: (comment) => {
        this.comments.set({
          ...this.comments(),
          [showId]: [comment, ...(this.comments()[showId] || [])]
        });
        this.newCommentContent[showId] = '';
      }
    });
  }

  deleteComment(showId: string, commentId: string) {
    if (!confirm('Are you sure you want to delete this comment?')) return;

    this.commentsService.deleteCommentFromShow(showId, commentId).subscribe({
      next: () => {
        this.comments.set({
          ...this.comments(),
          [showId]: (this.comments()[showId] || []).filter(c => c.id !== commentId)
        });
      }
    });
  }

  canEditComment(comment: Comment): boolean {
    const user = this.authService.user();
    if (!user) return false;
    return comment.userId === user.id || this.authService.isAdmin();
  }

  canDeleteComment(comment: Comment): boolean {
    const user = this.authService.user();
    if (!user) return false;
    return comment.userId === user.id || this.authService.isAdmin();
  }

  startEditComment(showId: string, comment: Comment) {
    this.editingCommentId.set(comment.id);
    this.editCommentContent = comment.rawContent ?? comment.content;
  }

  cancelCommentEdit() {
    this.editingCommentId.set(null);
    this.editCommentContent = '';
  }

  saveCommentEdit(showId: string, commentId: string) {
    if (!this.editCommentContent.trim()) return;

    this.commentsService.updateCommentOnShow(showId, commentId, this.editCommentContent).subscribe({
      next: (updatedComment) => {
        this.comments.set({
          ...this.comments(),
          [showId]: (this.comments()[showId] || []).map(c =>
            c.id === commentId ? updatedComment : c
          )
        });
        this.cancelCommentEdit();
      }
    });
  }

  // Suggestion methods
  toggleSuggestForm() {
    this.showSuggestForm.update(v => !v);
    if (!this.showSuggestForm()) {
      this.resetSuggestForm();
    }
  }

  resetSuggestForm() {
    this.suggestedShow = {
      title: '',
      type: ShowType.tvSeries,
      notes: '',
      coverImage: undefined
    };
    this.suggestShowImagePreview.set(null);
    this.imageError.set(null);
  }

  async submitSuggestion() {
    if (!this.suggestedShow.title) return;

    try {
      await this.suggestionService.createSuggestion({
        entityType: SuggestionEntity.show,
        title: this.suggestedShow.title,
        type: this.suggestedShow.type,
        notes: this.suggestedShow.notes,
        coverImage: this.suggestedShow.coverImage
      });
      alert('Thank you for your suggestion! It will be reviewed soon.');
      this.toggleSuggestForm();
    } catch {
      alert('Failed to submit suggestion. Please try again.');
    }
  }

  handleCommentEdit(showId: string, event: { commentId: string; content: string }) {
    this.commentsService.updateCommentOnShow(showId, event.commentId, event.content).subscribe({
      next: (updatedComment) => {
        this.comments.set({
          ...this.comments(),
          [showId]: (this.comments()[showId] || []).map(c =>
            c.id === event.commentId ? updatedComment : c
          )
        });
      }
    });
  }

  getCommentsSignal(showId: string) {
    return signal(this.comments()[showId] || []);
  }
}
