import { ComponentFixture, TestBed } from "@angular/core/testing";

import { AppComponent } from "./app.component";
import { Employment } from "./config/Employment";
import { Logos } from "./config/Logos";
import { Socials } from "./config/Socials";

describe("AppComponent", () => {
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent]
    }).compileComponents();
    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it("should create the app", () => {
    expect(component).toBeTruthy();
  });

  it(`should have the 'nhcarrigan' title`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual("nhcarrigan");
  });
});

describe("Configs", () => {
  it("employments should have correct oldest and newest", () => {
    const sorted = Employment.sort(
      (a, b) => b.start.getTime() - a.start.getTime()
    );
    const oldest = sorted.at(-1);
    const newest = sorted[0];
    expect(oldest?.title).toBe("Started Journey");
    expect(newest.company).toBe("Your Company!");
  });
  it("employments should have valid dates", () => {
    const sorted = [
      ...Employment.sort((a, b) => b.start.getTime() - a.start.getTime())
    ];
    const oldest = sorted.pop();
    const newest = sorted.shift();
    if (!oldest || !newest) {
      throw new Error("Failed to parse");
    }
    for (const job of sorted) {
      expect(job.start.getTime())
        .withContext(`${job.title} - ${job.company}`)
        .toBeGreaterThan(oldest.start.getTime());
      // Days should be set to the 5th - this ensures we're
      // within the correct month in all timezones.
      expect(job.start.getDate())
        .withContext(`${job.title} - ${job.company}`)
        .toBeGreaterThanOrEqual(4);
      expect(job.start.getDate())
        .withContext(`${job.title} - ${job.company}`)
        .toBeLessThanOrEqual(6);
      if (job.end) {
        expect(job.end.getTime())
          .withContext(`${job.title} - ${job.company}`)
          .toBeLessThan(newest.start.getTime());
        expect(job.end.getDate())
          .withContext(`${job.title} - ${job.company}`)
          .toBeGreaterThanOrEqual(4);
        expect(job.end.getDate())
          .withContext(`${job.title} - ${job.company}`)
          .toBeLessThanOrEqual(6);
      }
    }
  });
  it("logos should be unique", () => {
    const links = new Set(Logos.map((l) => l.link));
    const names = new Set(Logos.map((l) => l.alt));
    const files = new Set(Logos.map((l) => l.file));
    expect(links.size).toBe(Logos.length);
    expect(names.size).toBe(Logos.length);
    expect(files.size).toBe(Logos.length);
  });
  it("socials should be unique", () => {
    const names = new Set(Socials.map((s) => s.label));
    const links = new Set(Socials.map((s) => s.link));
    expect(links.size).toBe(Socials.length);
    expect(names.size).toBe(Socials.length);
  });
});
