import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule, FormControl } from '@angular/forms';
import { MatTableModule } from '@angular/material/table';
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 { 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 { MatDialogModule, MatDialog } from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { BehaviorSubject, Observable, Subject, debounceTime, distinctUntilChanged, map, switchMap, takeUntil } from 'rxjs';
import { BranchService, Branch } from './branch.service';

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

  // Observables
  branches$: Observable<Branch[]>;
  private branchesSubject = new BehaviorSubject<Branch[]>([]);
  private destroy$ = new Subject<void>();

  // Form controls
  searchInputControl = new FormControl('');
  selectedBranchForm!: FormGroup;

  // State management
  selectedBranch: Branch | null = null;
  isLoading = false;
  flashMessage: 'success' | 'error' | null = null;

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

  constructor(
    private fb: FormBuilder,
    private branchService: BranchService,
    private dialog: MatDialog,
    private snackBar: MatSnackBar
  ) {
    this.branches$ = this.branchesSubject.asObservable();
    this.initializeForm();
  }

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

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

  /**
   * Initialize the branch form
   */
  private initializeForm(): void {
    this.selectedBranchForm = this.fb.group({
      code: ['', [Validators.required, Validators.pattern(/^[A-Z0-9]+$/)]],
      name: ['', [Validators.required, Validators.minLength(3)]],
      location: ['', [Validators.required]],
      address: ['', [Validators.required, Validators.minLength(10)]],
      contact: ['', [Validators.required, Validators.pattern(/^[0-9]{10}$/)]]
    });
  }

  /**
   * Setup search functionality with debounce
   */
  private setupSearch(): void {
    this.searchInputControl.valueChanges
      .pipe(
        debounceTime(300),
        distinctUntilChanged(),
        takeUntil(this.destroy$)
      )
      .subscribe((searchTerm) => {
        this.filterBranches(searchTerm || '');
      });
  }

  /**
   * Load all branches from the backend
   */
  loadBranches(): void {
    this.isLoading = true;
    
    this.branchService.getAllBranches()
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (branches) => {
          this.branchesSubject.next(branches);
          this.pagination.length = branches.length;
          this.isLoading = false;
        },
        error: (error) => {
          console.error('Error loading branches:', error);
          this.showSnackBar('Failed to load branches', 'error');
          this.isLoading = false;
        }
      });
  }

  /**
   * Filter branches based on search term
   */
  private filterBranches(searchTerm: string): void {
    this.branchService.getAllBranches()
      .pipe(
        map(branches => {
          if (!searchTerm) {
            return branches;
          }
          
          const term = searchTerm.toLowerCase();
          return branches.filter(branch =>
            branch.name.toLowerCase().includes(term) ||
            branch.code.toLowerCase().includes(term) ||
            branch.location.toLowerCase().includes(term) ||
            branch.branch_id.toLowerCase().includes(term)
          );
        }),
        takeUntil(this.destroy$)
      )
      .subscribe(filtered => {
        this.branchesSubject.next(filtered);
        this.pagination.length = filtered.length;
      });
  }

  /**
   * Create new branch - open form
   */
  createBranch(): void {
    this.selectedBranch = {
      id: 0,
      branch_id: '',
      code: '',
      name: '',
      location: '',
      address: '',
      contact: '',
      created_at: '',
      updated_at: ''
    };
    
    this.selectedBranchForm.reset();
    this.flashMessage = null;
  }

  /**
   * Edit existing branch
   */
  editBranch(branch: Branch): void {
    this.selectedBranch = { ...branch };
    this.selectedBranchForm.patchValue({
      code: branch.code,
      name: branch.name,
      location: branch.location,
      address: branch.address,
      contact: branch.contact
    });
    this.flashMessage = null;
  }

  /**
   * Toggle branch details view
   */
  toggleDetails(branchId: number): void {
    if (this.selectedBranch?.id === branchId) {
      this.closeDetails();
    } else {
      const branch = this.branchesSubject.value.find(b => b.id === branchId);
      if (branch) {
        this.editBranch(branch);
      }
    }
  }

  /**
   * Close details panel
   */
  closeDetails(): void {
    this.selectedBranch = null;
    this.selectedBranchForm.reset();
    this.flashMessage = null;
  }

  /**
   * Update or create branch
   */
  updateSelectedBranch(): void {
    if (this.selectedBranchForm.invalid) {
      this.selectedBranchForm.markAllAsTouched();
      return;
    }

    this.isLoading = true;
    const formData = this.selectedBranchForm.value;

    const operation = this.selectedBranch?.id
      ? this.branchService.updateBranch(this.selectedBranch.id, formData)
      : this.branchService.createBranch(formData);

    operation
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (branch) => {
          this.flashMessage = 'success';
          this.isLoading = false;
          this.showSnackBar(
            this.selectedBranch?.id ? 'Branch updated successfully' : 'Branch created successfully',
            'success'
          );
          
          setTimeout(() => {
            this.closeDetails();
            this.loadBranches();
          }, 1500);
        },
        error: (error) => {
          console.error('Error saving branch:', error);
          this.flashMessage = 'error';
          this.isLoading = false;
          this.showSnackBar(
            error.error?.error || 'Failed to save branch',
            'error'
          );
        }
      });
  }

  /**
   * Delete selected branch
   */
  deleteSelectedBranch(): void {
    if (!this.selectedBranch?.id) {
      return;
    }

    if (!confirm(`Are you sure you want to delete branch "${this.selectedBranch.name}"?`)) {
      return;
    }

    this.deleteBranch(this.selectedBranch);
  }

  /**
   * Delete branch
   */
  deleteBranch(branch: Branch): void {
    if (!confirm(`Are you sure you want to delete branch "${branch.name}"?`)) {
      return;
    }

    this.isLoading = true;

    this.branchService.deleteBranch(branch.id)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: () => {
          this.showSnackBar('Branch deleted successfully', 'success');
          this.closeDetails();
          this.loadBranches();
        },
        error: (error) => {
          console.error('Error deleting branch:', error);
          this.showSnackBar(
            error.error?.error || 'Failed to delete branch',
            'error'
          );
          this.isLoading = false;
        }
      });
  }

  /**
   * Track by function for ngFor
   */
  trackByFn(index: number, item: Branch): number {
    return item.id;
  }

  /**
   * Show snackbar notification
   */
  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'
    });
  }
}