import { AuthService } from '../services/auth.service';
import { CandidateService } from '../services/candidate.service';
import { localStorageService } from '../services/local-storage.service';
import type { SaveCandidateInterface } from '../models/post/save-candidate.interface';
import type { AuthInterface } from '../models/auth.interface';

export interface RegisterInput {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  zip: string;
  zipName: string;
  subscribe: boolean;
}

export interface AuthActionResult {
  ok: boolean;
  message: string;
}

function getString(record: Record<string, unknown>, key: string): string | null {
  const value = record[key];
  return typeof value === 'string' ? value : null;
}

export class AuthViewModel {
  private authService: AuthService;
  private candidateService: CandidateService;

  constructor(
    authService: AuthService = new AuthService(),
    candidateService: CandidateService = new CandidateService(),
  ) {
    this.authService = authService;
    this.candidateService = candidateService;
  }

  async login(email: string, password: string, rememberMe: boolean): Promise<AuthActionResult> {
    const response = await this.authService.login(email, password);
    const record = (response ?? {}) as Record<string, unknown>;
    const token = getString(record, 'token');

    if (!token) {
      return {
        ok: false,
        message: 'Login fejlede: token mangler i svaret fra serveren.',
      };
    }

    const authData: AuthInterface = {
      id: getString(record, 'id') ?? '',
      token,
      email: getString(record, 'email') ?? email,
      runOutDate: 'forever',
    };

    await localStorageService.setAuthData(authData, rememberMe);

    return {
      ok: true,
      message: 'Du er nu logget ind.',
    };
  }

  async forgotPassword(email: string): Promise<AuthActionResult> {
    await this.authService.forgotPassword(email);
    return {
      ok: true,
      message: 'Anmodning om nulstilling af kodeord er sendt.',
    };
  }

  async register(input: RegisterInput): Promise<AuthActionResult> {
    const zip = Number.parseInt(input.zip, 10);
    if (Number.isNaN(zip)) {
      return {
        ok: false,
        message: 'Postnummer skal være et tal.',
      };
    }

    const payload: SaveCandidateInterface = {
      email: input.email,
      password: input.password,
      zip,
      zipName: input.zipName,
      awsUrl: '',
      latitude: 0,
      longitude: 0,
      firstName: input.firstName,
      lastName: input.lastName,
      subscribe: input.subscribe,
    };

    await this.candidateService.createAccountV2(payload);
    return {
      ok: true,
      message: 'Kontoen er oprettet.',
    };
  }
}
