import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { environment } from '../../../../../../environments/environment';

export interface Brand {
  id: number;
  brand_id: string;
  name: string;
  branch_id: string;
  branch_name: string;
  image: string | null;
  created_at: string;
  updated_at: string;
  
  // ⭐ NEW: Created by fields (automatic from backend)
  created_by?: number;
  created_by_username?: string;
}

@Injectable({
  providedIn: 'root'
})
export class BrandService {
  private apiUrl = `${environment.apiUrl}/brands`;

  constructor(private http: HttpClient) {}

  /**
   * Get authorization headers
   */
  private getHeaders(): HttpHeaders {
    const token = localStorage.getItem('accessToken');
    return new HttpHeaders({
      'Authorization': token ? `Bearer ${token}` : ''
    });
  }

  /**
   * Get all brands
   */
  getAllBrands(): Observable<Brand[]> {
    return this.http.get<Brand[]>(this.apiUrl, { headers: this.getHeaders() })
      .pipe(
        catchError(this.handleError)
      );
  }

  /**
   * Get single brand by ID
   */
  getBrand(id: number): Observable<Brand> {
    return this.http.get<Brand>(`${this.apiUrl}/${id}`, { headers: this.getHeaders() })
      .pipe(
        catchError(this.handleError)
      );
  }

  /**
   * Create new brand (with FormData for image upload)
   * ⭐ NOTE: Don't add created_by to FormData
   * Backend automatically extracts it from JWT token
   */
  createBrand(formData: FormData): Observable<Brand> {
    const token = localStorage.getItem('accessToken');
    const headers = new HttpHeaders({
      'Authorization': token ? `Bearer ${token}` : ''
      // Don't set Content-Type for FormData - browser sets it automatically with boundary
    });

    return this.http.post<Brand>(this.apiUrl, formData, { headers })
      .pipe(
        catchError(this.handleError)
      );
  }

  /**
   * Update existing brand (with FormData for image upload)
   * ⭐ NOTE: Don't update created_by
   * It's set once during creation and shouldn't change
   */
  updateBrand(id: number, formData: FormData): Observable<Brand> {
    const token = localStorage.getItem('accessToken');
    const headers = new HttpHeaders({
      'Authorization': token ? `Bearer ${token}` : ''
      // Don't set Content-Type for FormData - browser sets it automatically with boundary
    });

    return this.http.put<Brand>(`${this.apiUrl}/${id}`, formData, { headers })
      .pipe(
        catchError(this.handleError)
      );
  }

  /**
   * Delete brand
   */
  deleteBrand(id: number): Observable<{ message: string }> {
    return this.http.delete<{ message: string }>(`${this.apiUrl}/${id}`, { headers: this.getHeaders() })
      .pipe(
        catchError(this.handleError)
      );
  }

  /**
   * Search brands by query
   */
  searchBrands(query: string): Observable<Brand[]> {
    return this.http.get<Brand[]>(`${this.apiUrl}/search?q=${encodeURIComponent(query)}`, 
      { headers: this.getHeaders() })
      .pipe(
        catchError(this.handleError)
      );
  }

  /**
   * Get brands by branch
   */
  getBrandsByBranch(branchId: string): Observable<Brand[]> {
    return this.http.get<Brand[]>(`${this.apiUrl}/by-branch/${branchId}`, 
      { headers: this.getHeaders() })
      .pipe(
        catchError(this.handleError)
      );
  }

  /**
   * Handle HTTP errors
   */
  private handleError(error: any): Observable<never> {
    console.error('API Error:', error);
    
    let errorMessage = 'An error occurred';
    
    if (error.error instanceof ErrorEvent) {
      // Client-side error
      errorMessage = error.error.message;
    } else {
      // Server-side error
      errorMessage = error.error?.error || error.message || 'Server error';
    }
    
    return throwError(() => ({
      error: errorMessage,
      status: error.status
    }));
  }
}