import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule, FormControl } from '@angular/forms';
import { MatPaginatorModule, MatPaginator } from '@angular/material/paginator';
import { MatSortModule, MatSort } from '@angular/material/sort';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { BehaviorSubject, Observable, Subject, debounceTime, distinctUntilChanged, map, takeUntil } from 'rxjs';
import { CategoryService, Category } from './category.service';
import { BranchService, Branch } from '../../company/branch-list/branch.service';
import { BrandService, Brand } from '../brand/brand.service';

@Component({
  selector: 'app-categories',
  standalone: true,
  imports: [
    CommonModule, ReactiveFormsModule, MatPaginatorModule, MatSortModule,
    MatFormFieldModule, MatInputModule, MatSelectModule, MatButtonModule,
    MatIconModule, MatTooltipModule, MatProgressBarModule, MatSnackBarModule
  ],
  templateUrl: './categories.component.html',
  styleUrl: './categories.component.scss'
})
export class CategoriesComponent implements OnInit, OnDestroy {
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  categories$: Observable<Category[]>;
  private categoriesSubject = new BehaviorSubject<Category[]>([]);
  private destroy$ = new Subject<void>();

  searchInputControl = new FormControl('');
  selectedCategoryForm!: FormGroup;
  selectedCategory: Category | null = null;
  isLoading = false;
  flashMessage: 'success' | 'error' | null = null;

  pagination = { length: 0, page: 0, size: 10 };

  branches: Branch[] = [];
  brands: Brand[] = [];
  filteredBrands: Brand[] = [];

  selectedBranchId = '';
  selectedBranchName = '';
  selectedBrandId = '';
  previewCategoryId = 'XXX0001';

  imagePreview: string | null = null;
  selectedImageFile: File | null = null;

  constructor(
    private fb: FormBuilder,
    private categoryService: CategoryService,
    private branchService: BranchService,
    private brandService: BrandService,
    private snackBar: MatSnackBar
  ) {
    this.categories$ = this.categoriesSubject.asObservable();
    this.initializeForm();
  }

  ngOnInit(): void {
    this.loadBranches();
    this.loadBrands();
    this.loadCategories();
    this.setupSearch();
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  private initializeForm(): void {
    this.selectedCategoryForm = this.fb.group({
      name: ['', [Validators.required, Validators.minLength(2)]],
      branch_id: ['', [Validators.required]],
      brand_id: ['', [Validators.required]]
    });
  }

  private setupSearch(): void {
    this.searchInputControl.valueChanges.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      takeUntil(this.destroy$)
    ).subscribe((searchTerm) => {
      this.filterCategories(searchTerm || '');
    });
  }

  loadBranches(): void {
    this.branchService.getAllBranches().pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (branches) => { this.branches = branches; },
        error: (error) => this.showSnackBar('Failed to load branches', 'error')
      });
  }

  loadBrands(): void {
    this.brandService.getAllBrands().pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (brands) => { this.brands = brands; },
        error: (error) => this.showSnackBar('Failed to load brands', 'error')
      });
  }

  loadCategories(): void {
    this.isLoading = true;
    this.categoryService.getAllCategories().pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (categories) => {
          this.categoriesSubject.next(categories);
          this.pagination.length = categories.length;
          this.isLoading = false;
        },
        error: (error) => {
          this.showSnackBar('Failed to load categories', 'error');
          this.isLoading = false;
        }
      });
  }

  private filterCategories(searchTerm: string): void {
    this.categoryService.getAllCategories().pipe(
      map(categories => {
        if (!searchTerm) return categories;
        const term = searchTerm.toLowerCase();
        return categories.filter(cat =>
          cat.name.toLowerCase().includes(term) ||
          cat.category_id.toLowerCase().includes(term) ||
          cat.brand_name.toLowerCase().includes(term)
        );
      }),
      takeUntil(this.destroy$)
    ).subscribe(filtered => {
      this.categoriesSubject.next(filtered);
      this.pagination.length = filtered.length;
    });
  }

  onNameChange(event: any): void {
    const name = event.target.value;
    this.previewCategoryId = name ? this.generateCategoryIdPreview(name) : 'XXX0001';
  }

  private generateCategoryIdPreview(name: string): string {
    const lettersOnly = name.replace(/[^a-zA-Z]/g, '').toUpperCase();
    const prefix = lettersOnly.substring(0, 3).padEnd(3, 'X');
    return `${prefix}0001`;
  }

  onBranchChange(event: any): void {
    const branchId = event.value;
    const branch = this.branches.find(b => b.branch_id === branchId);
    
    if (branch) {
      this.selectedBranchId = branch.branch_id;
      this.selectedBranchName = branch.name;
      this.filteredBrands = this.brands.filter(b => b.branch_id === branchId);
      this.selectedCategoryForm.patchValue({ brand_id: '' });
      this.selectedBrandId = '';
    }
  }

  onBrandChange(event: any): void {
    const brandId = event.value;
    const brand = this.brands.find(b => b.brand_id === brandId);
    this.selectedBrandId = brand ? brand.brand_id : '';
  }

  onImageSelected(event: any): void {
    const file = event.target.files[0];
    if (file) {
      if (file.size > 5 * 1024 * 1024) {
        this.showSnackBar('Image size must be less than 5MB', 'error');
        return;
      }
      if (!file.type.startsWith('image/')) {
        this.showSnackBar('Please select an image file', 'error');
        return;
      }
      this.selectedImageFile = file;
      const reader = new FileReader();
      reader.onload = (e: any) => { this.imagePreview = e.target.result; };
      reader.readAsDataURL(file);
    }
  }

  removeImage(): void {
    this.imagePreview = null;
    this.selectedImageFile = null;
    if (this.selectedCategory?.id) this.selectedCategory.image = null;
  }

  getFullImageUrl(imagePath: string | null): string {
    if (!imagePath) return '';
    if (imagePath.startsWith('http')) return imagePath;
    return `http://localhost:5000${imagePath}`;
  }

  createCategory(): void {
    this.selectedCategory = {
      id: 0, category_id: '', name: '', image: null,
      brand_id: '', brand_name: '', branch_id: '', branch_name: '',
      created_at: '', updated_at: ''
    };
    this.selectedCategoryForm.reset();
    this.selectedBranchId = '';
    this.selectedBranchName = '';
    this.selectedBrandId = '';
    this.filteredBrands = [];
    this.previewCategoryId = 'XXX0001';
    this.imagePreview = null;
    this.selectedImageFile = null;
    this.flashMessage = null;
  }

  editCategory(category: Category): void {
    this.selectedCategory = { ...category };
    this.selectedCategoryForm.patchValue({
      name: category.name,
      branch_id: category.branch_id,
      brand_id: category.brand_id
    });
    this.selectedBranchId = category.branch_id;
    this.selectedBranchName = category.branch_name;
    this.selectedBrandId = category.brand_id;
    this.filteredBrands = this.brands.filter(b => b.branch_id === category.branch_id);
    this.previewCategoryId = category.category_id;
    this.imagePreview = category.image ? this.getFullImageUrl(category.image) : null;
    this.selectedImageFile = null;
    this.flashMessage = null;
  }

  toggleDetails(categoryId: number): void {
    if (this.selectedCategory?.id === categoryId) {
      this.closeDetails();
    } else {
      const category = this.categoriesSubject.value.find(c => c.id === categoryId);
      if (category) this.editCategory(category);
    }
  }

  closeDetails(): void {
    this.selectedCategory = null;
    this.selectedCategoryForm.reset();
    this.selectedBranchId = '';
    this.selectedBranchName = '';
    this.selectedBrandId = '';
    this.filteredBrands = [];
    this.previewCategoryId = 'XXX0001';
    this.imagePreview = null;
    this.selectedImageFile = null;
    this.flashMessage = null;
  }

  updateSelectedCategory(): void {
    if (this.selectedCategoryForm.invalid) {
      this.selectedCategoryForm.markAllAsTouched();
      return;
    }
    this.isLoading = true;
    const formData = new FormData();
    formData.append('name', this.selectedCategoryForm.get('name')?.value);
    formData.append('branch_id', this.selectedCategoryForm.get('branch_id')?.value);
    formData.append('brand_id', this.selectedCategoryForm.get('brand_id')?.value);
    if (this.selectedImageFile) formData.append('image', this.selectedImageFile);

    const operation = this.selectedCategory?.id
      ? this.categoryService.updateCategory(this.selectedCategory.id, formData)
      : this.categoryService.createCategory(formData);

    operation.pipe(takeUntil(this.destroy$)).subscribe({
      next: (category) => {
        this.flashMessage = 'success';
        this.isLoading = false;
        this.showSnackBar(
          this.selectedCategory?.id ? 'Category updated successfully' : 'Category created successfully',
          'success'
        );
        setTimeout(() => {
          this.closeDetails();
          this.loadCategories();
        }, 1500);
      },
      error: (error) => {
        this.flashMessage = 'error';
        this.isLoading = false;
        this.showSnackBar(error.error?.error || 'Failed to save category', 'error');
      }
    });
  }

  deleteSelectedCategory(): void {
    if (!this.selectedCategory?.id) return;
    if (!confirm(`Are you sure you want to delete category "${this.selectedCategory.name}"?`)) return;
    this.deleteCategory(this.selectedCategory);
  }

  deleteCategory(category: Category): void {
    if (!confirm(`Are you sure you want to delete category "${category.name}"?`)) return;
    this.isLoading = true;
    this.categoryService.deleteCategory(category.id).pipe(takeUntil(this.destroy$))
      .subscribe({
        next: () => {
          this.showSnackBar('Category deleted successfully', 'success');
          this.closeDetails();
          this.loadCategories();
        },
        error: (error) => {
          this.showSnackBar(error.error?.error || 'Failed to delete category', 'error');
          this.isLoading = false;
        }
      });
  }

  trackByFn(index: number, item: Category): number {
    return item.id;
  }

  private showSnackBar(message: string, type: 'success' | 'error'): void {
    this.snackBar.open(message, 'Close', {
      duration: 3000,
      horizontalPosition: 'end',
      verticalPosition: 'top',
      panelClass: type === 'success' ? 'snackbar-success' : 'snackbar-error'
    });
  }
}