import { EmployeeCourseAssessmentResponse, EmployeeMiniAssessmentResponse } from 'app/models/assessment/employee-assessment.model';
import { Email } from 'app/models/email';
import { SetupWorkspacePayload } from 'app/models/sandbox-progress.model';
import { CandidateDashboardResponse } from 'app/models/candidate-dashboard-response/candidate-dashboard-response';
import {  CANDIDATE_STATUS_NAMES } from 'app/models/candidateStatus';
import { PrimarySkillsTimeline } from './primary-skills-timeline';

export enum EventStatus {
  ACTIVE = 'Active',
  INPROGRESS = 'InProgress',
  COMPLETED = 'Completed',
  Completed =  'COMPLETED'
}

export enum UseCaseNames {
  Technical = 'Technical',
  Business = 'Business'
}

export const UseCases = {
  Technical: { id: 2, name: UseCaseNames.Technical },
  Business: { id: 3, name: UseCaseNames.Business }
};

export interface PrimarySkillsDetails {
  assessmentId: string;
  skillMaster: string;
  skills: string[];
  scheduleExpiryDate: number;
  adId: string;
  testLink?: string;
  PrimarySkillEvaluationStatus?: EventStatus;
}

// export interface PrimarySkillsTimeline {
//   expDate: number;
//   scheduledAt: Date;
//   state: string;
//   score: number;
// }

export interface Coach {
  adId: string;
  fullName: string;
  jobId: string;
}

export interface User {
  userInfoMstrId: number;
  emailId: string;
  adId: string;
  mettlStatus: string;
}

export interface AssessmentDetails {
  employeeAssessmentMappingId: any;
  assessmentStatus: any;
}
export interface TechnicalUsecase {
  user: User;
  coach?: Coach;
  courseId?: number;
  sandboxDir?: SetupWorkspacePayload;
}
export interface PrimarySkills {
  coach?: Coach;
  user: User;
  primarySkillsDetails: PrimarySkillsDetails;
  timeline: PrimarySkillsTimeline;
}

export interface IAssessment {
  primarySkills: PrimarySkills;
  technicalUsecase?: TechnicalUsecase;
  assessmentDetails?: AssessmentDetails;
}

export class Assessment implements IAssessment {
  public primarySkills: PrimarySkills = {
    coach: {
      adId: '',
      fullName: '',
      jobId: ''
    },
    user: {
      userInfoMstrId: 0,
      emailId: '',
      adId: '',
      mettlStatus: ''
    },
    primarySkillsDetails: {
      assessmentId: '',
      skillMaster: '',
      skills: [''],
      scheduleExpiryDate: 0,
      adId: ''
    },
    timeline: {
      expDate: 0,
      scheduledAt: new Date(),
      state: '',
      score: 0
    }
  };
  public technicalUsecase: TechnicalUsecase = {
    coach: {
      adId: '',
      fullName: '',
      jobId: ''
    },
    user: {
      userInfoMstrId: 0,
      emailId: '',
      adId: '',
      mettlStatus: ''
    },
    courseId: 1,
    sandboxDir: {
      sname: '',
      sbundleId: '',
      sdirId: ''
    }
  };
  public assessmentDetails: AssessmentDetails =  { employeeAssessmentMappingId: null, assessmentStatus: ''};

  setAssessment(data: any) {
    if (data) {
      /* TODO: Implement a deep type check to avoid nulls on child properties. */
      let typeSafeResponse = {
        infoMstr: {
          status: CANDIDATE_STATUS_NAMES.ONBOARDED, userInfoMstrId: null, emailId: null,
          pgUserSkillMapping: [{ pgSkillTrackDtls: { skillTrackDtlsName: null } }]
        },
        infoDetails: { adId: null, userInfoMstr: { pgUserSkillMapping: [{ pgSkillTrackDtls: { pgSkillTrackMstr: { skillTrackName: null } } }] } },
        coachDetails: [{ adId: null, fullName: null, jobId: null }],
        scheduleCandidateDetails: {
          expiryDate: null,
          scheduleDetails: {
            pgAssessmentDtls: {
              assessmentId: null,
              pgSkillTrackMstr: { skillTrackName: null },
              pgSkillCategory: { skillCategoryName: null },
              skillTrackDtlsName: null,
              createdDt: null
            }
          },
          testLink: null
        },
        eventDetails: [{ eventScore: null }],
        employeeEventDetails: [{eventScore: null, eventSts: null }, { eventScore: null, eventSts: null }],
        employeeCourseDetails: { courseId: null},
        employeeSkillMasterName: null,
        adId: null
      };
      if (data.coachDetails && data.coachDetails.length === 0) {
        data.coachDetails = null;
      }

      const typeSafeResponseBkp = { ...typeSafeResponse };
      typeSafeResponse = Object.assign(typeSafeResponse, data);

      // since the value coming in data its null make it typesafe again
      if (typeSafeResponse.scheduleCandidateDetails == null) {
        typeSafeResponse.scheduleCandidateDetails = { ...typeSafeResponseBkp.scheduleCandidateDetails };
      }

      const adId = typeSafeResponse.adId || typeSafeResponse.infoDetails.adId;
      const scheduleExpiryDate = typeSafeResponse.scheduleCandidateDetails.expiryDate;
      const mettlStatus = typeSafeResponse.infoMstr.status;
      const skills = typeSafeResponse.infoMstr.pgUserSkillMapping.map(skill => skill.pgSkillTrackDtls.skillTrackDtlsName);

      let score = 0;
      if (typeSafeResponse.employeeEventDetails[1].eventScore) {
        score = parseInt(typeSafeResponse.employeeEventDetails[1].eventScore, 10);
      } else {
        score = parseInt(typeSafeResponse.eventDetails[0].eventScore, 10);
      }

      this.primarySkills = {
        coach: (typeSafeResponse.coachDetails != null ? typeSafeResponse.coachDetails[0] : null),
        user: {
          userInfoMstrId: typeSafeResponse.infoMstr.userInfoMstrId,
          emailId: typeSafeResponse.infoMstr.emailId,
          adId: adId,
          mettlStatus: mettlStatus
        },
        primarySkillsDetails: {
          assessmentId: typeSafeResponse.scheduleCandidateDetails.scheduleDetails.pgAssessmentDtls.assessmentId,
          skillMaster: typeSafeResponse.employeeSkillMasterName || typeSafeResponse.scheduleCandidateDetails.scheduleDetails.pgAssessmentDtls.pgSkillTrackMstr.skillTrackName,
          skills: skills,
          /* TODO: get skills from skillMaster
          skillName: typeSafeResponse.infoDetails.userInfoMstr.pgUserSkillMapping[0].pgSkillTrackDtls.pgSkillTrackMstr.skillTrackName,
          */
          scheduleExpiryDate: scheduleExpiryDate,
          adId: adId,
          testLink: typeSafeResponse.scheduleCandidateDetails.testLink,
          PrimarySkillEvaluationStatus: typeSafeResponse.employeeEventDetails[1].eventSts
        },
        timeline: {
          expDate: scheduleExpiryDate,
          scheduledAt: typeSafeResponse.scheduleCandidateDetails.scheduleDetails.pgAssessmentDtls.createdDt,
          state: mettlStatus,
          score: score
        }
      };
      this.technicalUsecase = {
        user: this.primarySkills.user,
        coach: this.primarySkills.coach,
        courseId: typeSafeResponse.employeeCourseDetails.courseId,
        sandboxDir: {
          sname: '',
          sbundleId: '',
          sdirId: ''
        }
      };
    }
  }
  setMiniAssessment(data: any) {
    if (data) {
      /* TODO: Implement a deep type check to avoid nulls on child properties. */
      let typeSafeResponse = {
        infoMstr: {
          status: CANDIDATE_STATUS_NAMES.ONBOARDED, userInfoMstrId: null, emailId: null,
          pgUserSkillMapping: [{ pgSkillTrackDtls: { skillTrackDtlsName: null } }]
        },
        infoDetails: { adId: null, userInfoMstr: { pgUserSkillMapping: [{ pgSkillTrackDtls: { pgSkillTrackMstr: { skillTrackName: null } } }] } },
        coachDetails: [{ adId: null, fullName: null, jobId: null }],
        scheduleCandidateDetails: {
          expiryDate: null,
          scheduleDetails: {
            pgAssessmentDtls: {
              assessmentId: null,
              pgSkillTrackMstr: { skillTrackName: null },
              pgSkillCategory: { skillCategoryName: null },
              skillTrackDtlsName: null,
              createdDt: null
            }
          },
          testLink: null
        },
        eventDetails: [{ eventScore: null }],
        employeeEventDetails: [{eventScore: null, eventSts: null }, { eventScore: null, eventSts: null }],
        employeeCourseDetails: { courseId: null},
        assessmentDetails: { employeeAssessmentMappingId: null, assessmentStatus: '', coachDetails: {coachName: null}},
        employeeSkillMasterName: null,
        adId: null
      };
      if (data.coachDetails && data.coachDetails.length === 0) {
        data.coachDetails = null;
      }

      const typeSafeResponseBkp = { ...typeSafeResponse };
      typeSafeResponse = Object.assign(typeSafeResponse, data);

      // since the value coming in data its null make it typesafe again
      /*if (typeSafeResponse.scheduleCandidateDetails == null) {
        typeSafeResponse.scheduleCandidateDetails = { ...typeSafeResponseBkp.scheduleCandidateDetails };
      }
*/
      console.log(typeSafeResponse, 'typeSafeResponse');
      const adId = typeSafeResponse.adId || typeSafeResponse.infoDetails.adId;
      const scheduleExpiryDate = typeSafeResponse.scheduleCandidateDetails.expiryDate;
      const mettlStatus = typeSafeResponse.infoMstr.status;
      const skills = typeSafeResponse.infoMstr.pgUserSkillMapping.map(skill => skill.pgSkillTrackDtls.skillTrackDtlsName);

      let score = 0;
      if (typeSafeResponse.employeeEventDetails[0].eventScore) {
        score = parseInt(typeSafeResponse.employeeEventDetails[1].eventScore, 10);
      } else {
        score = parseInt(typeSafeResponse.eventDetails[0].eventScore, 10);
      }

      this.primarySkills = {
        coach: {
          fullName: typeSafeResponse.assessmentDetails.coachDetails.coachName,
          adId: '',
          jobId: ''
        },
        user: {
          userInfoMstrId: typeSafeResponse.infoMstr.userInfoMstrId,
          emailId: typeSafeResponse.infoMstr.emailId,
          adId: adId,
          mettlStatus: mettlStatus
        },
        primarySkillsDetails: {
          assessmentId: typeSafeResponse.scheduleCandidateDetails.scheduleDetails.pgAssessmentDtls.assessmentId,
          skillMaster: typeSafeResponse.employeeSkillMasterName || typeSafeResponse.scheduleCandidateDetails.scheduleDetails.pgAssessmentDtls.pgSkillTrackMstr.skillTrackName,
          skills: skills,
          /* TODO: get skills from skillMaster
          skillName: typeSafeResponse.infoDetails.userInfoMstr.pgUserSkillMapping[0].pgSkillTrackDtls.pgSkillTrackMstr.skillTrackName,
          */
          scheduleExpiryDate: scheduleExpiryDate,
          adId: adId,
          testLink: typeSafeResponse.scheduleCandidateDetails.testLink,
          PrimarySkillEvaluationStatus: typeSafeResponse.employeeEventDetails[0].eventSts
        },
        timeline: {
          expDate: scheduleExpiryDate,
          scheduledAt: typeSafeResponse.scheduleCandidateDetails.scheduleDetails.pgAssessmentDtls.createdDt,
          state: mettlStatus,
          score: score
        }
      };
      this.technicalUsecase = {
        user: this.primarySkills.user,
        coach: this.primarySkills.coach,
        courseId: typeSafeResponse.assessmentDetails.employeeAssessmentMappingId,
        sandboxDir: {
          sname: '',
          sbundleId: '',
          sdirId: ''
        }
      };
      this.assessmentDetails = { employeeAssessmentMappingId: typeSafeResponse.assessmentDetails.employeeAssessmentMappingId, assessmentStatus: typeSafeResponse.assessmentDetails.assessmentStatus};
    }
  }

  public setCandidateAssessment(candidateDashboard: CandidateDashboardResponse) {
    this.setAssessment(candidateDashboard);
  }

  public setEmployeeAssessment(employeeAssessment: EmployeeCourseAssessmentResponse) {
    if (employeeAssessment) {
      const coachDetails = {
        coachDetails: [{
          adId: 'Coach',
          fullName: employeeAssessment.coachName,
          jobId: employeeAssessment.coachJobId
        }]
      };
      employeeAssessment = Object.assign(employeeAssessment, coachDetails);
    }
    employeeAssessment.infoMstr.status = employeeAssessment.employeeCourseDetails.courseStatus;
    this.setAssessment(employeeAssessment);
  }

  public setEmployeeMiniAssessment(employeeAssessment: EmployeeMiniAssessmentResponse) {
    if (employeeAssessment) {
      const coachDetails = {
        coachDetails: [{
          adId: 'Coach',
          fullName: employeeAssessment.coachName,
          jobId: employeeAssessment.coachJobId
        }]
      };
      employeeAssessment = Object.assign(employeeAssessment, coachDetails);
    }
    employeeAssessment.infoMstr.status = employeeAssessment.assessmentDetails.assessmentStatus;
    this.setMiniAssessment(employeeAssessment);
  }
}

