export type Message = {
  messageId: string;
  messageType: string;
  receivedDateTime: string;
  sender: string;
};

export type GetMessageListResponse = {
  checkedDateTime: string;
  messages: Message[];
  code?: number;
  text?: string;
};

export enum MedipostAction {
  GetPublicMessageList = 'GetPublicMessageList',
  GetPublicMessage = 'GetPublicMessage',
  SendPrivateMessage = 'SendPrivateMessage',
  GetPrivateMessageList = 'GetPrivateMessageList',
  GetPrivateMessage = 'GetPrivateMessage',
  DeletePrivateMessage = 'DeletePrivateMessage',
}

export type VoimalikVaartus = {
  VaartusId: string;
  Vaartus: 'jah' | 'ei';
  VaartusJarjekord: number;
};

export type Sisendparameeter = {
  '@_VastuseTyyp'?: 'ARV' | 'VABATEKST' | 'KODEERITUD' | 'AJAHETK';
  '@_VastuseKoodistikuOID'?: string;
  '@_VastuseKoodistikuNimi'?: string;
  '@_URL'?: string;

  UuringIdOID: string;
  UuringId: string;
  TLyhend: string;
  KNimetus: string;
  UuringNimi: string;
  Jarjekord: number;

  VoimalikVaartus: VoimalikVaartus[];
};

export type Kood = {
  HkKood: string;
  HkKoodiKordaja: number;
  Koefitsient: number; // float
  Hind: number; // float
};

export type UuringuAlamElement = {
  UuringIdOID: string;
  UuringId: string;
  TLyhend: string;
  KNimetus: string;
  UuringNimi: string;
  Jarjekord: string;
  Kood?: Kood[];
};

export type UuringuElement = {
  UuringIdOID: string;
  UuringId: string;
  TLyhend: string;
  KNimetus: string;
  UuringNimi: string;
  Jarjekord: string;
  Kood?: Kood[];
  UuringuElement?: UuringuAlamElement[];
};

export type Uuring = {
  tellitav: 'JAH' | 'EI';
  UuringuElement: UuringuElement; //1..1
  MaterjalideGrupp?: MaterjalideGrupp | MaterjalideGrupp[]; //0..n If this is not present, then the analysis can't be ordered.
};

export type UuringuGrupp = {
  UuringuGruppId: string;
  UuringuGruppNimi: string;
  UuringuGruppJarjekord: number;
  Uuring: Uuring | Uuring[]; //1..n
  Kood?: Kood | Kood[]; //0..n
};

export type Konteiner = {
  ProovinouKoodOID?: string; //0..1
  ProovinouKood?: string; //0..1
  KonteineriNimi?: string; //0..1
  KonteineriKirjeldus: string; //1..1
};

export type Materjal = {
  MaterjaliTyypOID: string;
  MaterjaliTyyp: string;
  MaterjaliNimi: string;
  KonteineriOmadus: string;
  MaterjaliPaige: { Kohustuslik: 'JAH' | 'EI' }; //0..1
  MaterjalJarjekord?: number; //0..1
  Konteiner?: Konteiner | Konteiner[]; //0..n
};

export type MaterjalideGrupp = {
  vaikimisi: 'JAH' | 'EI';
  Materjal: Materjal | Materjal[]; //1..n
};

export type Teostaja = {
  UuringuGrupp?: UuringuGrupp | UuringuGrupp[]; //0...n
  Asutus: {
    AsutuseId: string;
    AsutuseNimi: string;
    AsutuseKood: string;
    AllyksuseNimi: string;
    Telefon: number;
    Aadress: string;
  };
  Sisendparameeter?: Sisendparameeter | Sisendparameeter[]; //0...n
};

export type MedipostPublicMessageResponse = {
  '?xml': {
    '@_version': string;
    '@_encoding': string;
    '@_standalone'?: 'yes' | 'no';
  };
  ANSWER?: { CODE: number };
  Saadetis?: {
    Pais: {
      Pakett: { '#text': 'SL' | 'OL' | 'AL' | 'ME' }; // SL - Teenused, OL - Tellimus (meie poolt saadetav saatekiri), AL - Vastus (saatekirja vastus), ME - Teade
      Saatja: string;
      Saaja: string;
      Aeg: string;
      SaadetisId: string;
    };
    Teenused: {
      Teostaja: Teostaja | Teostaja[]; //1..n
    };
  };
};

export type UuringuVastus = {
  VastuseVaartus: number; // text according to docs, but based on examples and logically, float
  VastuseAeg: string;
  NormYlem?: {
    '#text': number;
    '@_kaasaarvatud': string;
  }; // 0..1
  NormAlum?: {
    '#text': number;
    '@_kaasaarvatud': string;
  };
  NormiStaatus: keyof typeof NormStatus;
  ProoviJarjenumber: number;
};

export type ResponseUuring = {
  UuringuElement: {
    UuringIdOID: string;
    UuringId: string;
    TLyhend: string;
    KNimetus: string;
    UuringNimi: string;
    TellijaUuringId: number;
    TeostajaUuringId: string;
    UuringOlek: keyof typeof AnalysisOrderStatus;
    Mootyhik?: string; // 0..1
    Kood: {
      HkKood: number;
      HkKoodiKordaja: number;
      Koefitsient: number;
      Hind: number;
    };
    UuringuVastus?: UuringuVastus | UuringuVastus[]; // 0..n
    UuringuKommentaar?: string;
  }; // 1..1
  UuringuTaitjaAsutuseJnr: number;
};

export type ResponseUuringuGrupp = {
  UuringuGruppId: string;
  UuringuGruppNimi: string;
  Uuring: ResponseUuring | ResponseUuring[]; // 1..n
};

// type for UuringuGrupp is correct, but some of this is generated by an LLM and should be checked if data in use
export type MedipostOrderResponse = {
  '?xml': {
    '@_version': string;
    '@_encoding': string;
    '@_standalone': 'yes' | 'no';
  };
  ANSWER?: { CODE: number };
  Saadetis: {
    Pais: {
      Pakett: {
        '#text': string;
        '@_versioon': string;
      };
      Saatja: string;
      Saaja: string;
      Aeg: string;
      SaadetisId: string;
      Email: string;
    };
    Vastus: {
      ValisTellimuseId: number;
      Asutus: {
        '@_tyyp': string; // TEOSTAJA
        '@_jarjenumber': string;
        AsutuseId: number;
        AsutuseNimi: string;
        AsutuseKood: string;
        AllyksuseNimi?: string;
        Telefon: number;
      }[]; //@_tyyp = TELLIJA 1..1, @_tyyp = TEOSTAJA 1..n
      Personal: {
        '@_tyyp': string;
        '@_jarjenumber': string;
        PersonalOID: string;
        PersonalKood: string;
        PersonalPerekonnaNimi: string;
        PersonalEesNimi: string;
        Telefon: number;
      };
      Patsient: {
        IsikukoodiOID: string;
        Isikukood: string;
        PerekonnaNimi: string;
        EesNimi: string;
        SynniAeg: string;
        SuguOID: string;
        Sugu: string;
      };
      Proov: Array<{
        ProovinouIdOID: string;
        ProovinouId: string;
        MaterjaliTyypOID: string;
        MaterjaliTyyp: number;
        MaterjaliNimi: string;
        Ribakood: string;
        Jarjenumber: number;
        VotmisAeg: string;
        SaabumisAeg: string;
      }>;
      TellimuseNumber: string;
      TellimuseOlek: keyof typeof AnalysisOrderStatus;
      UuringuGrupp?: ResponseUuringuGrupp | ResponseUuringuGrupp[];
    };
  };
};

export const AnalysisOrderStatus: Record<number, string> = {
  1: 'QUEUED',
  2: 'ON_HOLD',
  3: 'PROCESSING',
  4: 'COMPLETED',
  5: 'REJECTED',
  6: 'CANCELLED',
};
export const NormStatus: Record<number, string> = {
  1: 'NORMAL',
  2: 'WARNING',
  3: 'REQUIRES_ATTENTION',
};
