/**
 * @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 { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { GamesService } from '../../services/games.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 { Game, GameStatus, CreateGameDto, UpdateGameDto, Comment, SuggestionEntity, Link } from '@library/shared-types';

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

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

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

          <div class="form-group">
            <label for="platform">Platform</label>
            <input
              type="text"
              id="platform"
              [(ngModel)]="newGame.platform"
              name="platform"
              placeholder="PC, PS5, Xbox, Switch, etc."
            >
          </div>

          <div class="form-group">
            <label for="status">Status</label>
            <select id="status" [(ngModel)]="newGame.status" name="status" required>
              <option [value]="GameStatus.playing">Currently Playing</option>
              <option [value]="GameStatus.completed">Completed</option>
              <option [value]="GameStatus.backlog">In Backlog</option>
              <option [value]="GameStatus.retired">Retired</option>
            </select>
          </div>

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

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

          <div class="form-group">
            <label for="rating">Rating (1-10)</label>
            <input
              type="number"
              id="rating"
              [(ngModel)]="newGame.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)]="newGameTimeHours"
                name="timeHours"
                min="0"
                placeholder="0"
                (ngModelChange)="updateNewGameTimeSpent()"
              >
            </div>
            <div class="form-group">
              <label for="timeMinutes">Time Spent (Minutes)</label>
              <input
                type="number"
                id="timeMinutes"
                [(ngModel)]="newGameTimeMinutes"
                name="timeMinutes"
                min="0"
                max="59"
                placeholder="0"
                (ngModelChange)="updateNewGameTimeSpent()"
              >
            </div>
          </div>

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

          <div class="form-group">
            <label for="series">Series (optional)</label>
            <input
              type="text"
              id="series"
              [(ngModel)]="newGame.series"
              name="series"
              placeholder="e.g., The Legend of Zelda"
            >
          </div>

          <div class="form-group">
            <label for="seriesOrder">Series Order (optional)</label>
            <input
              type="number"
              id="seriesOrder"
              [(ngModel)]="newGame.seriesOrder"
              name="seriesOrder"
              min="1"
              placeholder="Order in series"
            >
          </div>

          <div class="form-group">
            <label for="coverImage">Box Art (max 500KB)</label>
            <input
              type="file"
              id="coverImage"
              name="coverImage"
              accept="image/*"
              (change)="onImageSelected($event, 'new')"
            >
            @if (newGameImagePreview()) {
              <div class="image-preview">
                <img [src]="newGameImagePreview()" alt="Box art 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 newGame.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 newGame.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., Steam)"
              >
              <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 Game</button>
            <button type="button" (click)="toggleAddForm()" class="btn btn-secondary">Cancel</button>
          </div>
        </form>
      }

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

          <div class="form-group">
            <label for="edit-platform">Platform</label>
            <input
              type="text"
              id="edit-platform"
              [(ngModel)]="editGame.platform"
              name="platform"
              placeholder="PC, PS5, Xbox, Switch, etc."
            >
          </div>

          <div class="form-group">
            <label for="edit-status">Status</label>
            <select id="edit-status" [(ngModel)]="editGame.status" name="status" required>
              <option [value]="GameStatus.playing">Currently Playing</option>
              <option [value]="GameStatus.completed">Completed</option>
              <option [value]="GameStatus.backlog">In Backlog</option>
              <option [value]="GameStatus.retired">Retired</option>
            </select>
          </div>

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

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

          <div class="form-group">
            <label for="edit-rating">Rating (1-10)</label>
            <input
              type="number"
              id="edit-rating"
              [(ngModel)]="editGame.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)]="editGameTimeHours"
                name="timeHours"
                min="0"
                placeholder="0"
                (ngModelChange)="updateEditGameTimeSpent()"
              >
            </div>
            <div class="form-group">
              <label for="edit-timeMinutes">Time Spent (Minutes)</label>
              <input
                type="number"
                id="edit-timeMinutes"
                [(ngModel)]="editGameTimeMinutes"
                name="timeMinutes"
                min="0"
                max="59"
                placeholder="0"
                (ngModelChange)="updateEditGameTimeSpent()"
              >
            </div>
          </div>

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

          <div class="form-group">
            <label for="edit-series">Series (optional)</label>
            <input
              type="text"
              id="edit-series"
              [(ngModel)]="editGame.series"
              name="series"
              placeholder="e.g., The Legend of Zelda"
            >
          </div>

          <div class="form-group">
            <label for="edit-seriesOrder">Series Order (optional)</label>
            <input
              type="number"
              id="edit-seriesOrder"
              [(ngModel)]="editGame.seriesOrder"
              name="seriesOrder"
              min="1"
              placeholder="Order in series"
            >
          </div>

          <div class="form-group">
            <label for="edit-coverImage">Box Art (max 500KB)</label>
            <input
              type="file"
              id="edit-coverImage"
              name="coverImage"
              accept="image/*"
              (change)="onImageSelected($event, 'edit')"
            >
            @if (editGameImagePreview()) {
              <div class="image-preview">
                <img [src]="editGameImagePreview()" alt="Box art 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 editGame.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 editGame.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., Steam)"
              >
              <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 Game</h3>
          <p class="suggest-note">Your suggestion will be reviewed by Naomi. If accepted, it will be added to the backlog!</p>
          <div class="form-group">
            <label for="suggest-title">Title</label>
            <input
              type="text"
              id="suggest-title"
              [(ngModel)]="suggestedGame.title"
              name="title"
              required
              placeholder="Enter game title"
            >
          </div>

          <div class="form-group">
            <label for="suggest-platform">Platform</label>
            <input
              type="text"
              id="suggest-platform"
              [(ngModel)]="suggestedGame.platform"
              name="platform"
              placeholder="PC, PS5, Xbox, Switch, etc."
            >
          </div>

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

          <div class="form-group">
            <label for="suggest-coverImage">Box Art (max 500KB)</label>
            <input
              type="file"
              id="suggest-coverImage"
              name="coverImage"
              accept="image/*"
              (change)="onImageSelected($event, 'suggest')"
            >
            @if (suggestGameImagePreview()) {
              <div class="image-preview">
                <img [src]="suggestGameImagePreview()" alt="Box art 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" role="search" aria-label="Game search and filters">
        <label for="game-search" class="sr-only">Search games</label>
        <input
          type="search"
          id="game-search"
          [value]="searchQuery()"
          (input)="searchQuery.set($any($event.target).value); currentPage.set(1)"
          name="search"
          placeholder="Search by title, platform, or notes..."
          class="search-input"
          aria-label="Search by title, platform, or notes"
        >
        <button
          (click)="toggleFilters()"
          class="btn btn-secondary btn-sm"
          [attr.aria-expanded]="showFilters()"
          aria-controls="advanced-filters"
          type="button"
        >
          {{ showFilters() ? 'Hide' : 'Show' }} Advanced Filters
          @if (selectedTags().length > 0) {
            <span aria-label="{{ selectedTags().length }} active filters">({{ selectedTags().length }})</span>
          }
        </button>
        @if (searchQuery() || selectedTags().length > 0) {
          <button (click)="clearFilters()" class="btn btn-secondary btn-sm" type="button">
            Clear All Filters
          </button>
        }
      </div>

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

      <div class="filters" role="group" aria-label="Filter games by status">
        <button
          (click)="setFilter('all')"
          [class.active]="statusFilter() === 'all'"
          [attr.aria-pressed]="statusFilter() === 'all'"
          class="filter-btn"
          type="button"
        >
          All ({{ games().length }})
        </button>
        <button
          (click)="setFilter(GameStatus.playing)"
          [class.active]="statusFilter() === GameStatus.playing"
          [attr.aria-pressed]="statusFilter() === GameStatus.playing"
          class="filter-btn"
          type="button"
        >
          Playing ({{ playingCount() }})
        </button>
        <button
          (click)="setFilter(GameStatus.completed)"
          [class.active]="statusFilter() === GameStatus.completed"
          [attr.aria-pressed]="statusFilter() === GameStatus.completed"
          class="filter-btn"
          type="button"
        >
          Completed ({{ completedCount() }})
        </button>
        <button
          (click)="setFilter(GameStatus.backlog)"
          [class.active]="statusFilter() === GameStatus.backlog"
          [attr.aria-pressed]="statusFilter() === GameStatus.backlog"
          class="filter-btn"
          type="button"
        >
          Backlog ({{ backlogCount() }})
        </button>
        <button
          (click)="setFilter(GameStatus.retired)"
          [class.active]="statusFilter() === GameStatus.retired"
          [attr.aria-pressed]="statusFilter() === GameStatus.retired"
          class="filter-btn"
          type="button"
        >
          Retired ({{ retiredCount() }})
        </button>
      </div>

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

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

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

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

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

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

        <app-pagination
          [currentPage]="currentPage()"
          [pageSize]="pageSize()"
          [totalItems]="totalFilteredGames()"
          (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 #ff6b6b;
      box-shadow: 0 4px 12px rgba(255, 107, 107, 0.3);
      transition: all 0.3s;
    }

    .page-avatar:hover {
      transform: scale(1.05);
      box-shadow: 0 8px 16px rgba(255, 107, 107, 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 #ff6b6b;
      background: #fff9f9;
    }

    .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: #ff6b6b;
    }

    .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: #ff6b6b;
      background: #fef2f2;
    }

    .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;
    }

    .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: #ff6b6b;
      color: white;
    }

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

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

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

    .game-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;
    }

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

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

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

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

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

    .game-info {
      padding: 1rem;
    }

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

    .platform {
      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;
      margin: 0.5rem 0;
    }

    .status-playing { background: #fef3c7; color: #92400e; }
    .status-completed { background: #d1fae5; color: #065f46; }
    .status-backlog { background: #e0e7ff; color: #3730a3; }
    .status-retired { background: #f3f4f6; color: #4b5563; }

    .rating {
      margin: 0.5rem 0;
    }

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

    .rating span.filled {
      color: #f59e0b;
    }

    .card-actions {
      padding: 0.75rem 1rem;
      border-top: 1px solid #e5e7eb;
      display: flex;
      align-items: center;
      gap: 0.75rem;
      flex-wrap: wrap;
    }

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

    .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: #ff6b6b; 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; }

    /* Tags and Links Styling for Forms */
    .tags-input-container {
      display: flex;
      flex-wrap: wrap;
      gap: 0.5rem;
      align-items: center;
      padding: 0.5rem;
      border: 1px solid #ccc;
      border-radius: 4px;
      background: white;
    }

    .tags-input-container input {
      border: none;
      outline: none;
      flex: 1;
      min-width: 150px;
      padding: 0.25rem;
    }

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

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

    .tag-remove:hover {
      color: #fecaca;
    }

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

    .link-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0.25rem 0;
      border-bottom: 1px solid #eee;
    }

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

    .link-add-form input {
      flex: 1;
      min-width: 120px;
    }

    .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: #10b981;
    }

    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border-width: 0;
    }
  `]
})
export class GamesListComponent implements OnInit {
  gamesService = inject(GamesService);
  authService = inject(AuthService);
  commentsService = inject(CommentsService);
  sanitizeService = inject(SanitizeService);
  suggestionService = inject(SuggestionService);

  games = signal<Game[]>([]);
  loading = signal(true);
  showAddForm = signal(false);
  editingGame = signal<Game | null>(null);
  statusFilter = signal<'all' | GameStatus>('all');

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

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

  // Comments state
  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 = '';

  // Image upload state
  newGameImagePreview = signal<string | null>(null);
  editGameImagePreview = signal<string | null>(null);
  suggestGameImagePreview = signal<string | null>(null);
  imageError = signal<string | null>(null);
  private readonly MAX_IMAGE_SIZE = 500 * 1024; // 500KB

  // Suggestion state
  showSuggestForm = signal(false);
  suggestedGame: { title: string; platform?: string; notes?: string; coverImage?: string } = {
    title: '',
    platform: '',
    notes: '',
    coverImage: undefined
  };

  // Expose GameStatus enum to template
  GameStatus = GameStatus;

  // Computed signals for reactive count updates
  playingCount = computed(() => this.games().filter(game => game.status === GameStatus.playing).length);
  completedCount = computed(() => this.games().filter(game => game.status === GameStatus.completed).length);
  backlogCount = computed(() => this.games().filter(game => game.status === GameStatus.backlog).length);
  retiredCount = computed(() => this.games().filter(game => game.status === GameStatus.retired).length);

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

  filteredGames = computed(() => {
    let games = this.games();

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

    // Apply search filter
    const searchQuery = this.searchQuery().toLowerCase().trim();
    if (searchQuery) {
      games = games.filter(game =>
        game.title.toLowerCase().includes(searchQuery) ||
        game.platform?.toLowerCase().includes(searchQuery) ||
        game.notes?.toLowerCase().includes(searchQuery)
      );
    }

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

    return games;
  });

  paginatedGames = computed(() => {
    const games = this.filteredGames();
    const start = (this.currentPage() - 1) * this.pageSize();
    const end = start + this.pageSize();
    return games.slice(start, end);
  });

  totalFilteredGames = computed(() => this.filteredGames().length);

  newGame: Partial<CreateGameDto> & { dateStarted?: Date; dateFinished?: Date } = {
    title: '',
    platform: '',
    status: GameStatus.backlog,
    dateStarted: undefined,
    dateFinished: undefined,
    rating: undefined,
    notes: '',
    tags: [],
    links: []
  };

  editGame: Partial<UpdateGameDto> = {};

  // Time tracking state
  newGameTimeHours = 0;
  newGameTimeMinutes = 0;
  editGameTimeHours = 0;
  editGameTimeMinutes = 0;

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

  ngOnInit() {
    this.loadGames();
  }

  loadGames() {
    this.loading.set(true);
    this.gamesService.getAllGames().subscribe({
      next: (games) => {
        this.games.set(games);
        this.loading.set(false);
      },
      error: () => {
        this.loading.set(false);
      }
    });
  }

  setFilter(filter: 'all' | GameStatus) {
    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: GameStatus): string {
    switch (status) {
      case GameStatus.playing: return 'Currently Playing';
      case GameStatus.completed: return 'Completed';
      case GameStatus.backlog: return 'In Backlog';
      case GameStatus.retired: return 'Retired';
    }
  }

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

  resetForm() {
    this.newGame = {
      title: '',
      platform: '',
      status: GameStatus.backlog,
      dateStarted: undefined,
      dateFinished: undefined,
      rating: undefined,
      notes: '',
      coverImage: undefined,
      tags: [],
      links: []
    };
    this.newGameTimeHours = 0;
    this.newGameTimeMinutes = 0;
    this.newGameImagePreview.set(null);
    this.imageError.set(null);
    this.newTagInput = '';
    this.newLinkTitle = '';
    this.newLinkUrl = '';
  }

  updateNewGameTimeSpent() {
    const totalMinutes = (this.newGameTimeHours * 60) + this.newGameTimeMinutes;
    this.newGame.timeSpent = totalMinutes > 0 ? totalMinutes : undefined;
  }

  updateEditGameTimeSpent() {
    const totalMinutes = (this.editGameTimeHours * 60) + this.editGameTimeMinutes;
    this.editGame.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.newGame.tags = [...(this.newGame.tags || []), input];
      this.newTagInput = '';
    } else {
      this.editGame.tags = [...(this.editGame.tags || []), input];
      this.editTagInput = '';
    }
  }

  removeTag(index: number, target: 'new' | 'edit') {
    if (target === 'new') {
      this.newGame.tags = (this.newGame.tags || []).filter((_, i) => i !== index);
    } else {
      this.editGame.tags = (this.editGame.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.newGame.links = [...(this.newGame.links || []), { title, url }];
      this.newLinkTitle = '';
      this.newLinkUrl = '';
    } else {
      this.editGame.links = [...(this.editGame.links || []), { title, url }];
      this.editLinkTitle = '';
      this.editLinkUrl = '';
    }
  }

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

  addGame() {
    if (!this.newGame.title || !this.newGame.status) return;

    const gameToAdd: CreateGameDto = {
      title: this.newGame.title,
      platform: this.newGame.platform,
      status: this.newGame.status,
      rating: this.newGame.rating,
      notes: this.newGame.notes,
      coverImage: this.newGame.coverImage,
      dateStarted: this.newGame.dateStarted ? new Date(this.newGame.dateStarted) : undefined,
      dateFinished: this.newGame.dateFinished ? new Date(this.newGame.dateFinished) : undefined,
      tags: this.newGame.tags || [],
      links: this.newGame.links || []
    };

    this.gamesService.createGame(gameToAdd).subscribe(() => {
      this.loadGames();
      this.toggleAddForm();
    });
  }

  deleteGame(game: Game) {
    if (confirm(`Are you sure you want to delete "${game.title}"?`)) {
      this.gamesService.deleteGame(game.id).subscribe(() => {
        this.loadGames();
      });
    }
  }

  startEdit(game: Game) {
    this.editingGame.set(game);
    this.editGame = {
      title: game.title,
      platform: game.platform,
      status: game.status,
      dateStarted: game.dateStarted,
      dateFinished: game.dateFinished,
      rating: game.rating,
      notes: game.notes,
      coverImage: game.coverImage,
      tags: [...(game.tags || [])],
      links: [...(game.links || [])],
      series: game.series,
      seriesOrder: game.seriesOrder,
      timeSpent: game.timeSpent
    };
    // Populate time fields from existing timeSpent
    if (game.timeSpent) {
      this.editGameTimeHours = Math.floor(game.timeSpent / 60);
      this.editGameTimeMinutes = game.timeSpent % 60;
    } else {
      this.editGameTimeHours = 0;
      this.editGameTimeMinutes = 0;
    }
    this.editGameImagePreview.set(game.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.editingGame.set(null);
    this.editGame = {};
    this.editGameImagePreview.set(null);
    this.imageError.set(null);
    this.editTagInput = '';
    this.editLinkTitle = '';
    this.editLinkUrl = '';
  }

  saveEdit() {
    const game = this.editingGame();
    if (!game || !this.editGame.title || !this.editGame.status) return;

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

    this.gamesService.updateGame(game.id, updateData).subscribe(() => {
      this.loadGames();
      this.cancelEdit();
    });
  }

  // Image handling methods
  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.newGameImagePreview.set(base64);
        this.newGame.coverImage = base64;
      } else if (target === 'edit') {
        this.editGameImagePreview.set(base64);
        this.editGame.coverImage = base64;
      } else {
        this.suggestGameImagePreview.set(base64);
        this.suggestedGame.coverImage = base64;
      }
    };
    reader.readAsDataURL(file);
  }

  clearImage(target: 'new' | 'edit' | 'suggest') {
    if (target === 'new') {
      this.newGameImagePreview.set(null);
      this.newGame.coverImage = undefined;
    } else if (target === 'edit') {
      this.editGameImagePreview.set(null);
      this.editGame.coverImage = undefined;
    } else {
      this.suggestGameImagePreview.set(null);
      this.suggestedGame.coverImage = undefined;
    }
    this.imageError.set(null);
  }

  // Comments methods
  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(gameId: string) {
    const expanded = this.expandedComments();
    const isCurrentlyExpanded = expanded[gameId];

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

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

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

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

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

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

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

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

    this.commentsService.deleteCommentFromGame(gameId, commentId).subscribe({
      next: () => {
        this.comments.set({
          ...this.comments(),
          [gameId]: (this.comments()[gameId] || []).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(gameId: string, comment: Comment) {
    this.editingCommentId.set(comment.id);
    this.editCommentContent = comment.rawContent ?? comment.content;
  }

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

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

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

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

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

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

  resetSuggestForm() {
    this.suggestedGame = {
      title: '',
      platform: '',
      notes: '',
      coverImage: undefined
    };
    this.suggestGameImagePreview.set(null);
    this.imageError.set(null);
  }

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

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