import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { NoteDetailComponent } from '../note-detail/note-detail.component';
import { NoteService } from '../../services/note.service';
import { ClarityModule } from '@clr/angular';

describe('NoteDetailComponent', () => {
  let component: NoteDetailComponent;
  let fixture: ComponentFixture<NoteDetailComponent>;
  let noteServiceSpy: jasmine.SpyObj<NoteService>;
  let router: Router;
  let activatedRoute: ActivatedRoute;

  const mockNote = { id: '1', title: 'Test Note', content: 'Test Content', createdAt: '2023-01-01', updatedAt: '2023-01-01' };

  beforeEach(async () => {
    noteServiceSpy = jasmine.createSpyObj('NoteService', ['getNoteById', 'deleteNote']);
    noteServiceSpy.getNoteById.and.returnValue(of(mockNote));
    noteServiceSpy.deleteNote.and.returnValue(of(void 0));

    await TestBed.configureTestingModule({
      declarations: [ NoteDetailComponent ],
      imports: [ ClarityModule, RouterTestingModule.withRoutes([]) ],
      providers: [
        { provide: NoteService, useValue: noteServiceSpy },
        { provide: ActivatedRoute, useValue: { paramMap: of({ get: (key: string) => '1' }) } }
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(NoteDetailComponent);
    component = fixture.componentInstance;
    router = TestBed.inject(Router);
    activatedRoute = TestBed.inject(ActivatedRoute);
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should load note on init', () => {
    expect(noteServiceSpy.getNoteById).toHaveBeenCalledWith('1');
    expect(component.note).toEqual(mockNote);
  });

  it('should navigate to edit on editNote', () => {
    spyOn(router, 'navigate');
    component.note = mockNote;
    component.editNote();
    expect(router.navigate).toHaveBeenCalledWith(['/notes/edit', mockNote.id]);
  });

  it('should delete note on deleteNote confirmation', () => {
    spyOn(window, 'confirm').and.returnValue(true);
    spyOn(router, 'navigate');
    component.note = mockNote;
    component.deleteNote();
    expect(noteServiceSpy.deleteNote).toHaveBeenCalledWith(mockNote.id);
    expect(router.navigate).toHaveBeenCalledWith(['/notes']);
  });

  it('should not delete note on deleteNote cancellation', () => {
    spyOn(window, 'confirm').and.returnValue(false);
    spyOn(router, 'navigate');
    component.note = mockNote;
    component.deleteNote();
    expect(noteServiceSpy.deleteNote).not.toHaveBeenCalled();
    expect(router.navigate).not.toHaveBeenCalledWith(['/notes']);
  });
});
