// user.component.ts - UPDATED WITH DYNAMIC ROLE FETCHING
import { Component, OnInit, OnDestroy, ViewChild, ChangeDetectorRef } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { MatPaginator, MatPaginatorModule, PageEvent } from '@angular/material/paginator';
import { MatSort, MatSortModule, Sort } from '@angular/material/sort';
import { MatProgressBarModule } from '@angular/material/progress-bar';
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 { MatSelectModule } from '@angular/material/select';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatTooltipModule } from '@angular/material/tooltip';
import { CommonModule } from '@angular/common';
import { Observable, Subject, BehaviorSubject, combineLatest } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, startWith, takeUntil } from 'rxjs/operators';
import { User, UserService, UserDocument, DocumentWithMetadata } from '../user/user.service';
import { AuthService } from 'app/core/auth/auth.service';
import { RoleService, Role } from '../role-management/role-management.service'; // IMPORT ROLE SERVICE

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

  // Observables
  users$!: Observable<User[]>;
  private _unsubscribeAll: Subject<any> = new Subject<any>();
  
  // Data
  dataSource = new MatTableDataSource<User>();
  private _users: BehaviorSubject<User[]> = new BehaviorSubject<User[]>([]);
  
  // UI State
  isLoading: boolean = false;
  selectedUser: User | null = null;
  flashMessage: 'success' | 'error' | null = null;
  
  // Role-based properties - UPDATED TO USE DYNAMIC ROLES
  currentUserRole: string | null = null;
  isClient: boolean = false;
  isAdmin: boolean = false;
  availableRoles: { value: string; label: string }[] = [];
  allRoles: Role[] = []; // Store all roles from database
  rolesLoading: boolean = false;
  
  // Forms
  searchInputControl: FormControl = new FormControl('');
  selectedUserForm: FormGroup;
  
  // File handling
  selectedPhoto: File | null = null;
  selectedLogo: File | null = null;
  selectedDocuments: Array<{
    file: File;
    documentType: string;
    documentTypeOther?: string;
  }> = [];
  photoPreview: string | null = null;
  logoPreview: string | null = null;
  
  // Document types
  documentTypes = [
    { value: 'aadhar', label: 'Aadhar Card' },
    { value: 'pan', label: 'PAN Card' },
    { value: 'gst', label: 'GST Certificate' },
    { value: 'msme', label: 'MSME Certificate' },
    { value: 'fssai', label: 'FSSAI License' },
    { value: 'other', label: 'Other' }
  ];
  
  // For viewing documents
  viewingDocument: UserDocument | null = null;
  
  // Pagination
  pagination = {
    length: 0,
    page: 0,
    size: 10
  };

  constructor(
    private _userService: UserService,
    private _formBuilder: FormBuilder,
    private _changeDetectorRef: ChangeDetectorRef,
    private _authService: AuthService,
    private _roleService: RoleService // INJECT ROLE SERVICE
  ) {
    // Initialize form
    this.selectedUserForm = this._formBuilder.group({
      username: ['', [Validators.required]],
      email: ['', [Validators.required, Validators.email]],
      contact: ['', [Validators.required, Validators.pattern('^[0-9]{10}$')]],
      roles: ['', [Validators.required]],
      user_status: ['Active'],
      password: ['', [Validators.required, Validators.minLength(6)]]
    });
  }

  ngOnInit(): void {
    // Get current user role
    this.currentUserRole = this._authService.userRole;
    this.isClient = this._authService.hasRole('Client');
    this.isAdmin = this._authService.hasAnyRole(['Management', 'SuperAdmin', 'Admin']);
    
    console.log('User Management - Current Role:', this.currentUserRole);
    
    // Load roles from database
    this.loadRolesFromDatabase();
    
    this.users$ = this._users.asObservable();

    this.searchInputControl.valueChanges
      .pipe(
        takeUntil(this._unsubscribeAll),
        debounceTime(300),
        distinctUntilChanged(),
        startWith('')
      )
      .subscribe(() => {
        this.filterUsers();
      });

    this.loadUsers();
  }

  /**
   * UPDATED: Load roles from database instead of hardcoded values
   */
  private loadRolesFromDatabase(): void {
    this.rolesLoading = true;
    
    this._roleService.getRoles()
      .pipe(takeUntil(this._unsubscribeAll))
      .subscribe(
        (roles: Role[]) => {
          console.log('✓ Roles loaded from database:', roles);
          this.allRoles = roles;
          
          // Filter roles based on current user's permissions
          this.setAvailableRoles(roles);
          
          this.rolesLoading = false;
          this._changeDetectorRef.markForCheck();
        },
        (error) => {
          console.error('✗ Error loading roles:', error);
          this.rolesLoading = false;
          
          // Fallback to empty roles if error
          this.availableRoles = [];
          this._changeDetectorRef.markForCheck();
        }
      );
  }

  /**
   * UPDATED: Filter roles based on current user's role (from database)
   */
  private setAvailableRoles(roles: Role[]): void {
    let filteredRoles: Role[] = [];
    
    if (this.isClient) {
      // Clients can ONLY assign Refiller role
      filteredRoles = roles.filter(role => role.name === 'Refiller');
      console.log('Client role - Filtered to Refiller only');
    } else if (this.isAdmin) {
      // Admins can assign any role from database
      filteredRoles = roles;
      console.log('Admin role - All roles available');
    } else {
      // Other roles - no permissions to assign roles
      filteredRoles = [];
      console.log('Other role - No role assignment permissions');
    }
    
    // Convert to dropdown format
    this.availableRoles = this._roleService.rolesToDropdownFormat(filteredRoles);
    
    console.log('Available roles for dropdown:', this.availableRoles);
  }

  /**
   * Refresh roles from database
   */
  refreshRoles(): void {
    console.log('Refreshing roles from database...');
    this.loadRolesFromDatabase();
  }

  ngOnDestroy(): void {
    this._unsubscribeAll.next(null);
    this._unsubscribeAll.complete();
  }

  ngAfterViewInit(): void {
    if (this.paginator) {
      this.paginator.page
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe((page: PageEvent) => {
          this.pagination.page = page.pageIndex;
          this.pagination.size = page.pageSize;
          this.filterUsers();
        });
    }

    if (this.sort) {
      this.sort.sortChange
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe((sort: Sort) => {
          this.sortUsers(sort);
        });
    }
  }

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

  loadUsers(): void {
    this.isLoading = true;

    this._userService.getUsers()
      .pipe(takeUntil(this._unsubscribeAll))
      .subscribe(
        (users: User[]) => {
          // Filter users based on current user role
          let filteredUsers = users;
          
          if (this.isClient) {
            // Clients can only see Refillers they created
            filteredUsers = users.filter(u => u.roles === 'Refiller');
          }
          
          this._users.next(filteredUsers);
          this.pagination.length = filteredUsers.length;
          this.isLoading = false;
          this.filterUsers();
          this._changeDetectorRef.markForCheck();
        },
        (error) => {
          console.error('Error loading users:', error);
          this.isLoading = false;
          this.showFlashMessage('error');
        }
      );
  }

  filterUsers(): void {
    let filteredUsers = this._users.getValue();
    const searchTerm = this.searchInputControl.value?.toLowerCase() || '';

    if (searchTerm) {
      filteredUsers = filteredUsers.filter(user => 
        user.username.toLowerCase().includes(searchTerm) ||
        user.email.toLowerCase().includes(searchTerm) ||
        user.contact.includes(searchTerm) ||
        user.roles.toLowerCase().includes(searchTerm) ||
        (user.user_id && user.user_id.toLowerCase().includes(searchTerm))
      );
    }

    this.pagination.length = filteredUsers.length;
    
    const start = this.pagination.page * this.pagination.size;
    const end = start + this.pagination.size;
    filteredUsers = filteredUsers.slice(start, end);

    this.dataSource.data = filteredUsers;
    this._changeDetectorRef.markForCheck();
  }

  sortUsers(sort: Sort): void {
    const users = this._users.getValue().slice();
    
    if (!sort.active || sort.direction === '') {
      this._users.next(users);
      return;
    }

    const sortedUsers = users.sort((a, b) => {
      const isAsc = sort.direction === 'asc';
      switch (sort.active) {
        case 'id': return this.compare(a.id, b.id, isAsc);
        case 'user_id': return this.compare(a.user_id, b.user_id, isAsc);
        case 'username': return this.compare(a.username, b.username, isAsc);
        case 'email': return this.compare(a.email, b.email, isAsc);
        case 'contact': return this.compare(a.contact, b.contact, isAsc);
        case 'roles': return this.compare(a.roles, b.roles, isAsc);
        case 'user_status': return this.compare(a.user_status, b.user_status, isAsc);
        default: return 0;
      }
    });

    this._users.next(sortedUsers);
    this.filterUsers();
  }

  private compare(a: string | number | undefined, b: string | number | undefined, isAsc: boolean): number {
    return (a! < b! ? -1 : 1) * (isAsc ? 1 : -1);
  }

  toggleDetails(userId?: number): void {
    if (this.selectedUser && this.selectedUser.id === userId) {
      this.closeDetails();
      return;
    }

    const user = this._users.getValue().find(u => u.id === userId);
    if (user) {
      this.selectedUser = { ...user };
      this.selectedUserForm.patchValue({
        username: user.username,
        email: user.email,
        contact: user.contact,
        roles: user.roles,
        user_status: user.user_status
      });

      this.photoPreview = this._userService.getFullFileUrl(user.photo);
      this.logoPreview = this._userService.getFullFileUrl(user.company_logo);

      this.selectedUserForm.get('password')?.clearValidators();
      this.selectedUserForm.get('password')?.updateValueAndValidity();
    }
  }

  getFullFileUrl(path: string | undefined): string | null {
    return this._userService.getFullFileUrl(path);
  }

  closeDetails(): void {
    this.selectedUser = null;
    this.selectedPhoto = null;
    this.selectedLogo = null;
    this.selectedDocuments = [];
    this.photoPreview = null;
    this.logoPreview = null;
    this.viewingDocument = null;
  }

  createUser(): void {
    if (this.selectedUser) {
      this.closeDetails();
    }
    
    // For clients, auto-set role to Refiller
    const defaultRole = this.isClient ? 'Refiller' : '';
    
    const newUser: User = {
      username: '',
      email: '',
      contact: '',
      roles: defaultRole,
      user_status: 'Active',
      password: ''
    };

    this.selectedUser = newUser;
    
    this.selectedUserForm.reset();
    this.selectedUserForm.patchValue({
      user_status: 'Active',
      roles: defaultRole
    });

    this.selectedUserForm.get('password')?.setValidators([Validators.required, Validators.minLength(6)]);
    this.selectedUserForm.get('password')?.updateValueAndValidity();

    window.scrollTo({ top: 0, behavior: 'smooth' });
    this._changeDetectorRef.markForCheck();
  }

  onPhotoSelected(event: any): void {
    const file = event.target.files[0];
    if (file && file.type.startsWith('image/')) {
      this.selectedPhoto = file;
      
      const reader = new FileReader();
      reader.onload = (e: any) => {
        this.photoPreview = e.target.result;
        this._changeDetectorRef.markForCheck();
      };
      reader.readAsDataURL(file);
    }
  }

  onLogoSelected(event: any): void {
    const file = event.target.files[0];
    if (file && file.type.startsWith('image/')) {
      this.selectedLogo = file;
      
      const reader = new FileReader();
      reader.onload = (e: any) => {
        this.logoPreview = e.target.result;
        this._changeDetectorRef.markForCheck();
      };
      reader.readAsDataURL(file);
    }
  }

  onDocumentsSelected(event: any): void {
    const files = Array.from(event.target.files) as File[];
    
    files.forEach(file => {
      this.selectedDocuments.push({
        file: file,
        documentType: 'aadhar',
        documentTypeOther: ''
      });
    });
    
    this._changeDetectorRef.markForCheck();
  }

  removeDocument(index: number): void {
    this.selectedDocuments.splice(index, 1);
    this._changeDetectorRef.markForCheck();
  }

  updateDocumentType(index: number, type: string): void {
    this.selectedDocuments[index].documentType = type;
    if (type !== 'other') {
      this.selectedDocuments[index].documentTypeOther = '';
    }
    this._changeDetectorRef.markForCheck();
  }

  updateDocumentTypeOther(index: number, value: string): void {
    this.selectedDocuments[index].documentTypeOther = value;
    this._changeDetectorRef.markForCheck();
  }

  viewDocument(doc: UserDocument): void {
    this.viewingDocument = doc;

    const fullUrl = this._userService.getFullFileUrl(doc.path);
    if (!fullUrl) return;
    
    const fileExtension = doc.path.split('.').pop()?.toLowerCase();
    const viewableExtensions = ['pdf', 'jpg', 'jpeg', 'png', 'gif'];
    
    if (fileExtension && viewableExtensions.includes(fileExtension)) {
      window.open(fullUrl, '_blank');
    } else {
      const link = window.document.createElement('a');
      link.href = fullUrl;
      link.download = doc.filename;
      link.click();
    }
  }

  getDocumentTypeLabel(type: string): string {
    const docType = this.documentTypes.find(dt => dt.value === type);
    return docType ? docType.label : type;
  }

  getDocumentIcon(filename: string): string {
    const extension = filename.split('.').pop()?.toLowerCase();
    switch (extension) {
      case 'pdf': return 'picture_as_pdf';
      case 'doc':
      case 'docx': return 'description';
      case 'jpg':
      case 'jpeg':
      case 'png':
      case 'gif': return 'image';
      default: return 'insert_drive_file';
    }
  }

  deleteExistingDocument(documentPath: string): void {
    if (!this.selectedUser?.id) return;

    if (confirm('Are you sure you want to delete this document?')) {
      this.isLoading = true;
      
      this._userService.deleteUserDocument(this.selectedUser.id, documentPath)
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe(
          () => {
            if (this.selectedUser?.documents) {
              this.selectedUser.documents = this.selectedUser.documents.filter(
                doc => doc.path !== documentPath
              );
            }
            this.showFlashMessage('success');
            this.isLoading = false;
            this.loadUsers();
          },
          (error) => {
            console.error('Error deleting document:', error);
            this.showFlashMessage('error');
            this.isLoading = false;
          }
        );
    }
  }

  updateSelectedUser(): void {
    if (!this.selectedUserForm.valid) {
      return;
    }

    this.isLoading = true;
    const formValue = this.selectedUserForm.value;
    
    if (this.selectedUser?.id) {
      this._userService.updateUser(
        this.selectedUser.id,
        formValue,
        this.selectedPhoto || undefined,
        this.selectedLogo || undefined,
        this.selectedDocuments.length > 0 ? this.selectedDocuments : undefined
      )
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe(
          () => {
            this.loadUsers();
            this.showFlashMessage('success');
            this.closeDetails();
            this.isLoading = false;
          },
          (error) => {
            console.error('Error updating user:', error);
            this.showFlashMessage('error');
            this.isLoading = false;
          }
        );
    } else {
      this._userService.addUser(
        formValue,
        this.selectedPhoto || undefined,
        this.selectedLogo || undefined,
        this.selectedDocuments.length > 0 ? this.selectedDocuments : undefined
      )
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe(
          () => {
            this.loadUsers();
            this.showFlashMessage('success');
            this.closeDetails();
            this.isLoading = false;
          },
          (error) => {
            console.error('Error creating user:', error);
            this.showFlashMessage('error');
            this.isLoading = false;
          }
        );
    }
  }

  deleteSelectedUser(): void {
    if (!this.selectedUser?.id) {
      return;
    }

    if (confirm('Are you sure you want to delete this user? All associated files will be deleted.')) {
      this.isLoading = true;
      
      this._userService.deleteUser(this.selectedUser.id)
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe(
          () => {
            this.loadUsers();
            this.closeDetails();
            this.showFlashMessage('success');
            this.isLoading = false;
          },
          (error) => {
            console.error('Error deleting user:', error);
            this.showFlashMessage('error');
            this.isLoading = false;
          }
        );
    }
  }

  onStatusChange(event: any): void {
    const newStatus = event.checked ? 'Active' : 'Inactive';
    this.selectedUserForm.patchValue({
      user_status: newStatus
    });
    this._changeDetectorRef.markForCheck();
  }

  private showFlashMessage(type: 'success' | 'error'): void {
    this.flashMessage = type;
    
    setTimeout(() => {
      this.flashMessage = null;
      this._changeDetectorRef.markForCheck();
    }, 3000);
  }

  getFileSize(bytes: number): string {
    if (bytes < 1024) return bytes + ' B';
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
    return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
  }
}