# frozen_string_literal: true

class EmailChecker
  # Extracted 100 most used domain on our users table [june 2024]
  # + all .gouv.fr domain on our users table
  # + all .ac-xxx on our users table
  KNOWN_DOMAINS = [
    'gmail.com',
    'hotmail.fr',
    'orange.fr',
    'yahoo.fr',
    'hotmail.com',
    'outlook.fr',
    'wanadoo.fr',
    'free.fr',
    'yahoo.com',
    'icloud.com',
    'laposte.net',
    'live.fr',
    'sfr.fr',
    'outlook.com',
    'neuf.fr',
    'aol.com',
    'bbox.fr',
    'msn.com',
    'me.com',
    'gmx.fr',
    'protonmail.com',
    'club-internet.fr',
    'live.com',
    'ymail.com',
    'ars.sante.fr',
    'mail.ru',
    'cegetel.net',
    'numericable.fr',
    'aliceadsl.fr',
    'comcast.net',
    'assurance-maladie.fr',
    'mac.com',
    'naver.com',
    'airbus.com',
    'justice.fr',
    'pole-emploi.fr',
    'educagri.fr',
    'aphp.fr',
    'netcourrier.com',
    'dbmail.com',
    'aol.fr',
    'qq.com',
    'hotmail.co.uk',
    'yahoo.co.uk',
    'proxima-mail.fr',
    'yahoo.com.br',
    'sciencespo.fr',
    'gmx.com',
    'etu.univ-st-etienne.fr',
    'yahoo.ca',
    '163.com',
    'francetravail.fr',
    'mail.pf',
    'nantesmetropole.fr',
    'hotmail.it',
    'sbcglobal.net',
    'noos.fr',
    'ird.fr',
    'safrangroup.com',
    'croix-rouge.fr',
    'eiffage.com',
    'veolia.com',
    'notaires.fr',
    'nordnet.fr',
    'videotron.ca',
    'paris.fr',
    'lilo.org',
    'mfr.asso.fr',
    'yopmail.com',
    'ukr.net',
    'onf.fr',
    'stellantis.com',
    '9online.fr',
    'atmp50.fr',
    'engie.com',
    'libertysurf.fr',
    'mailo.com',
    'auchan.fr',
    'verizon.net',
    'rocketmail.com',
    'mpsa.com',
    'entrepreneur.fr',
    'googlemail.com',
    'arcelormittal.com',
    'groupe-sos.org',
    'proton.me',
    'att.net',
    'pm.me',
    'orange.com',
    'abv.bg',
    'yahoo.es',
    'creditmutuel.fr',
    'yandex.ru',
    'essec.edu',
    'urssaf.fr',
    'bpifrance.fr',
    'uol.com.br',
    'suez.com',
    'univ-st-etienne.fr',
    'korian.fr',
    'bnf.fr',
    'developpement-durable.gouv.fr',
    'modernisation.gouv.fr',
    'social.gouv.fr',
    'emploi.gouv.fr',
    'agriculture.gouv.fr',
    'intradef.gouv.fr',
    'interieur.gouv.fr',
    'oise.gouv.fr',
    'direccte.gouv.fr',
    'culture.gouv.fr',
    'pas-de-calais.gouv.fr',
    'finances.gouv.fr',
    'drieets.gouv.fr',
    'drjscs.gouv.fr',
    'sg.social.gouv.fr',
    'martinique.pref.gouv.fr',
    'beta.gouv.fr',
    'dieccte.gouv.fr',
    'cotes-darmor.gouv.fr',
    'vosges.gouv.fr',
    'developppement-durable.gouv.fr',
    'mayenne.gouv.fr',
    'aviation-civile.gouv.fr',
    'data.gouv.fr',
    'recherche.gouv.fr',
    'sante.gouv.fr',
    'paris-idf.gouv.fr',
    'guyane.gouv.fr',
    'douane.finances.gouv.fr',
    'cget.gouv.fr',
    'herault.gouv.fr',
    'loire-atlantique.gouv.fr',
    'manche.gouv.fr',
    'seine-maritime.gouv.fr',
    'dgccrf.finances.gouv.fr',
    'tarn-et-garonne.gouv.fr',
    'dila.gouv.fr',
    'diplomatie.gouv.fr',
    'haut-rhin.gouv.fr',
    'nord.gouv.fr',
    'bouches-du-rhone.gouv.fr',
    'alpes-de-haute-provence.gouv.fr',
    'hautes-alpes.gouv.fr',
    'alpes-maritimes.gouv.fr',
    'var.gouv.fr',
    'vaucluse.gouv.fr',
    'rhone.gouv.fr',
    'occitanie.gouv.fr',
    'ille-et-vilaine.gouv.fr',
    'finistere.gouv.fr',
    'aisne.gouv.fr',
    'indre.gouv.fr',
    'yvelines.gouv.fr',
    'bas-rhin.gouv.fr',
    'landes.gouv.fr',
    'haute-marne.gouv.fr',
    'correze.gouv.fr',
    'val-doise.gouv.fr',
    'seine-et-marne.gouv.fr',
    'essonne.gouv.fr',
    'calvados.gouv.fr',
    'charente-maritime.gouv.fr',
    'corse-du-sud.gouv.fr',
    'gironde.gouv.fr',
    'haute-corse.gouv.fr',
    'morbihan.gouv.fr',
    'pyrenees-atlantiques.gouv.fr',
    'pyrenees-orientales.gouv.fr',
    'somme.gouv.fr',
    'vendee.gouv.fr',
    'dgtresor.gouv.fr',
    'marne.gouv.fr',
    'auvergne-rhone-alpes.gouv.fr',
    'meurthe-et-moselle.gouv.fr',
    'pm.gouv.fr',
    'oncfs.gouv.fr',
    'orne.gouv.fr',
    'charente.gouv.fr',
    'travail.gouv.fr',
    'gard.gouv.fr',
    'maine-et-loire.gouv.fr',
    'moselle.gouv.fr',
    'outre-mer.gouv.fr',
    'jscs.gouv.fr',
    'haute-garonne.gouv.fr',
    'vienne.gouv.fr',
    'dordogne.gouv.fr',
    'eure.gouv.fr',
    'meuse.gouv.fr',
    'savoie.gouv.fr',
    'doubs.gouv.fr',
    'bfc.gouv.fr',
    'education.gouv.fr',
    'ariege.gouv.fr',
    'normandie.gouv.fr',
    'gendarmerie.interieur.gouv.fr',
    'ain.gouv.fr',
    'ardennes.gouv.fr',
    'drome.gouv.fr',
    'bretagne.gouv.fr',
    'paca.gouv.fr',
    'haute-saone.gouv.fr',
    'lot.gouv.fr',
    'dgfip.finances.gouv.fr',
    'aveyron.gouv.fr',
    'gers.gouv.fr',
    'tarn.gouv.fr',
    'aude.gouv.fr',
    'lozere.gouv.fr',
    'hautes-pyrenees.gouv.fr',
    'jeunesse-sports.gouv.fr',
    'alpes.maritimes.gouv.fr',
    'dreets.gouv.fr',
    'justice.gouv.fr',
    'sports.gouv.fr',
    'nouvelle-aquitaine.gouv.fr',
    'jura.gouv.fr',
    'haute-savoie.gouv.fr',
    'creuse.gouv.fr',
    'creps-poitiers.sports.gouv.fr',
    'equipement-agriculture.gouv.fr',
    'ira-metz.gouv.fr',
    'loire.gouv.fr',
    'defense.gouv.fr',
    'paris.gouv.fr',
    'ensm.sports.gouv.fr',
    'isere.gouv.fr',
    'haute-loire.gouv.fr',
    'cantal.gouv.fr',
    'lot-et-garonne.gouv.fr',
    'reunion.pref.gouv.fr',
    'loiret.gouv.fr',
    'indre-et-loire.gouv.fr',
    'eleve.ira-metz.gouv.fr',
    'deux-sevres.gouv.fr',
    'inao.gouv.fr',
    'franceconnect.gouv.fr',
    'essone.gouv.fr',
    'workinfrance.beta.gouv.fr',
    'seine-saint-denis.gouv.fr',
    'val-de-marne.gouv.fr',
    'morbihan.pref.gouv.fr',
    'externes.justice.gouv.fr',
    'haute-vienne.gouv.fr',
    'territoire-de-belfort.gouv.fr',
    'creps-reunion.sports.gouv.fr',
    'creps-centre.sports.gouv.fr',
    'creps-rhonealpes.sports.gouv.fr',
    'creps-montpellier.sports.gouv.fr',
    'nord.pref.gouv.fr',
    'charente-maritime.pref.gouv.fr',
    'cher.gouv.fr',
    'cote-dor.gouv.fr',
    'ssi.gouv.fr',
    'ira.gouv.fr',
    'pays-de-la-loire.gouv.fr',
    'loir-et-cher.gouv.fr',
    'saone-et-loire.gouv.fr',
    'enseignementsup.gouv.fr',
    'eure-et-loir.gouv.fr',
    'yonne.gouv.fr',
    'guadeloupe.pref.gouv.fr',
    'centre-val-de-loire.gouv.fr',
    'entreprise.api.gouv.fr',
    'grand-est.gouv.fr',
    'sarthe.gouv.fr',
    'sarthe.pref.gouv.fr',
    'puy-de-dome.gouv.fr',
    'externes.sante.gouv.fr',
    'allier.gouv.fr',
    'aube.gouv.fr',
    'nievre.gouv.fr',
    'ardeche.gouv.fr',
    'api.gouv.fr',
    'hauts-de-seine.gouv.fr',
    'hauts-de-france.gouv.fr',
    'temp-beta.gouv.fr',
    'def.gouv.fr',
    'particulier.api.gouv.fr',
    'ira-lille.gouv.fr',
    'haute-saone.pref.gouv.fr',
    'yvelines.pref.gouv.fr',
    'sgg.pm.gouv.fr',
    'anah.gouv.fr',
    'corse.gouv.fr',
    'mayenne.pref.gouv.fr',
    'cote-dor.pref.gouv.fr',
    'guyane.pref.gouv.fr',
    'ira-nantes.gouv.fr',
    'igas.gouv.fr',
    'tarn.pref.gouv.fr',
    'martinique.gouv.fr',
    'creps-paca.sports.gouv.fr',
    'ofb.gouv.fr',
    'loir-et-cher.pref.gouv.fr',
    'indre-et-loire.pref.gouv.fr',
    'polynesie-francaise.pref.gouv.fr',
    'scl.finances.gouv.fr',
    'numerique.gouv.fr',
    'cantal.pref.gouv.fr',
    'territoire-de-belfort.pref.gouv.fr',
    'creps-wattignies.sports.gouv.fr',
    'vienne.pref.gouv.fr',
    'ardennes.pref.gouv.fr',
    'creps-strasbourg.sports.gouv.fr',
    'creps-dijon.sports.gouv.fr',
    'ara.gouv.fr',
    'sgdsn.gouv.fr',
    'pays-de-la-loire.pref.gouv.fr',
    'anct.gouv.fr',
    'creps-pap.sports.gouv.fr',
    'sgae.gouv.fr',
    'esnm.sports.gouv.fr',
    'nouvelle-caledonie.gouv.fr',
    'deets.gouv.fr',
    'mayotte.gouv.fr',
    'creps-bordeaux.sports.gouv.fr',
    'civs.gouv.fr',
    'iga.interieur.gouv.fr',
    'cab.travail.gouv.fr',
    'ira-bastia.gouv.fr',
    'ira-lyon.gouv.fr',
    'creps-lorraine.sports.gouv.fr',
    'dihal.gouv.fr',
    'ofpra.gouv.fr',
    'mayotte.pref.gouv.fr',
    'strategie.gouv.fr',
    'territoires.gouv.fr',
    'dgcl.gouv.fr',
    'doubs.pref.gouv.fr',
    'service-civique.gouv.fr',
    'maine-et-loire.pref.gouv.fr',
    'envsn.sports.gouv.fr',
    'wallis-et-futuna.pref.gouv.fr',
    'gendarmerie.defense.gouv.fr',
    'anlci.gouv.fr',
    'cabinets.finances.gouv.fr',
    'seine-maritime.pref.gouv.fr',
    'promo46.ira-metz.gouv.fr',
    'aisne.pref.gouv.fr',
    'sportsdenature.gouv.fr',
    'loire-atlantique.pref.gouv.fr',
    'aude.pref.gouv.fr',
    'premier-ministre.gouv.fr',
    'igf.finances.gouv.fr',
    'eleves.ira-bastia.gouv.fr',
    'igesr.gouv.fr',
    'alpc.gouv.fr',
    'externes.emploi.gouv.fr',
    'prestataire.finances.gouv.fr',
    'gironde.pref.gouv.fr',
    'premar-atlantique.gouv.fr',
    'creps-toulouse.sports.gouv.fr',
    'guadeloupe.gouv.fr',
    'cybermalveillance.gouv.fr',
    'dicod.defense.gouv.fr',
    'creps-vichy.sports.gouv.fr',
    'aft.gouv.fr',
    'equipement.gouv.fr',
    'academie.defense.gouv.fr',
    'aube.pref.gouv.fr',
    'seine-et-marne.pref.gouv.fr',
    'pyrenees-orientales.pref.gouv.fr',
    'haute-garonne.pref.gouv.fr',
    'haut-rhin.pref.gouv.fr',
    'seine-saint-denis.pref.gouv.fr',
    'dcstep.gouv.fr',
    'promo47.ira-metz.gouv.fr',
    'trackdechets.beta.gouv.fr',
    'val-de-marne.pref.gouv.fr',
    'fabrique.social.gouv.fr',
    'agrasc.gouv.fr',
    'indre.pref.gouv.fr',
    'tarn-et-garonne.pref.gouv.fr',
    'corse.pref.gouv.fr',
    'bas-rhin.pref.gouv.fr',
    'inclusion.beta.gouv.fr',
    'hauts-de-seine.pref.gouv.fr',
    'loiret.pref.gouv.fr',
    'essonne.pref.gouv.fr',
    'territoires-industrie.gouv.fr',
    'spm975.gouv.fr',
    'saint-barth-saint-martin.gouv.fr',
    'judiciaire.interieur.gouv.fr',
    'mer.gouv.fr',
    'premar-manche.gouv.fr',
    'haute-normandie.pref.gouv.fr',
    'prestataire.modernisation.gouv.fr',
    'covoiturage.beta.gouv.fr',
    'promo48.ira-metz.gouv.fr',
    'france-services.gouv.fr',
    'ddets.gouv.fr',
    'afa.gouv.fr',
    'externes.social.gouv.fr',
    'vosges.pref.gouv.fr',
    'reunion.gouv.fr',
    'rhone.pref.gouv.fr',
    'alpes-maritimes.pref.gouv.fr',
    'gard.pref.gouv.fr',
    'oise.pref.gouv.fr',
    'creps-reims.sports.gouv.fr',
    'bouches-du-rhone.pref.gouv.fr',
    'esante.gouv.fr',
    'rhone-alpes.pref.gouv.fr',
    'finistere.pref.gouv.fr',
    'ops-bss.defense.gouv.fr',
    'orne.pref.gouv.fr',
    'transformation.gouv.fr',
    'cbcm.social.gouv.fr',
    'recosante.beta.gouv.fr',
    'pas-de-calais.pref.gouv.fr',
    'promo49.ira-metz.gouv.fr',
    'paca.pref.gouv.fr',
    'meurthe-et-moselle.pref.gouv.fr',
    'externes.sg.social.gouv.fr',
    'puy-de-dome.pref.gouv.fr',
    'academie.def.gouv.fr',
    'tarn.gouv.frd81intranet.ddcspp.tarn.gouv.fr',
    'agriculture-equipement.gouv.fr',
    'creps-idf.sports.gouv.fr',
    'eleve.ira-nantes.gouv.fr',
    'cohesion-territoires.gouv.fr',
    'ariege.pref.gouv.fr',
    'pyrenees-atlantiques.pref.gouv.fr',
    'hautes-pyrenees.pref.gouv.fr',
    'lot-et-garonne.pref.gouv.fr',
    'loire.pref.gouv.fr',
    'info-routiere.gouv.fr',
    'diges.gouv.fr',
    'insp.gouv.fr',
    'creps-pdl.sports.gouv.fr',
    'ddc.social.gouv.fr',
    'eleve.insp.gouv.fr',
    'val-doise.pref.gouv.fr',
    'montsaintmichel.gouv.fr',
    'st-cyr.terre-net.defense.gouv.fr',
    '.finances.gouv.fr',
    'logement.gouv.fr',
    'cotes-darmor.pref.gouv.fr',
    'marne.pref.gouv.fr',
    'herault.pref.gouv.fr',
    'viennne.gouv.fr',
    'landes.pref.gouv.fr',
    'moselle.pref.gouv.fr',
    'saone-et-loire.pref.gouv.fr',
    'bmpm.gouv.fr',
    'ecologie-territoires.gouv.fr',
    'nievre.pref.gouv.fr',
    'hautes-pyrénées.gouv.fr',
    'gic.gouv.fr',
    'industrie.gouv.fr',
    'lot.pref.gouv.fr',
    'plan.gouv.fr',
    'internet.gouv.fr',
    'mesads.beta.gouv.fr',
    'gers.pref.gouv.fr',
    'dordogne.pref.gouv.fr',
    'somme.pref.gouv.fr',
    'datasubvention.beta.gouv.fr',
    'anc.gouv.fr',
    'premar-mediterranee.gouv.fr',
    'ille-et-vilaine.pref.gouv.fr',
    'eure-et-loir.pref.gouv.fr',
    'prestataires.pm.gouv.fr',
    'snu.gouv.fr',
    'code.gouv.fr',
    'alsace.pref.gouv.fr',
    'haute-vienne.pref.gouv.fr',
    'yonne.pref.gouv.fr',
    'bretagne.pref.gouv.fr',
    'mastere.insp.gouv.fr',
    'cada.pm.gouv.fr',
    'creuse.pref.gouv.fr',
    'ecologie.gouv.fr',
    'midi-pyrenees.pref.gouv.fr',
    'promo54.ira-metz.gouv.fr',
    'var.pref.gouv.fr',
    'alpes-de-haute-provence.pref.gouv.fr',
    'mail.numerique.gouv.fr',
    'france-identite.gouv.fr',
    'transport.data.gouv.fr',
    'allier.pref.gouv.fr',
    'dilhal.gouv.fr',
    'ardeche.pref.gouv.fr',
    'haute-corse.pref.gouv.fr',
    'intérieur.gouv.fr',
    'ddfip.gouv.fr',
    'calvados.pref.gouv.fr',
    'territoir-de-belfort.gouv.fr',
    'nor.gouv.fr',
    'creps-occitanie.sports.gouv.fr',
    'developpement-durabe.gouv.fr',
    'educ.nat.gouv.fr',
    'developpement-duable.gouv.fr',
    'dgfip.finanes.gouv.fr',
    'loire-atlantqieu.gouv.fr',
    'promo55.ira-metz.gouv.fr',
    'haute-saône.gouv.fr',
    'developpement.durable.gouv.fr',
    'dreet.gouv.fr',
    'miprof.gouv.fr',
    'pref.guyane.gouv.fr',
    'developpement.gouv.fr',
    'gendamrerie.interieur.gouv.fr',
    'pyrenees-atlantique.gouv.fr',
    'apprentissage.beta.gouv.fr',
    'yveliens.gouv.fr',
    'justiice.gouv.fr',
    'cutlure.gouv.fr',
    'aidantsconnect.beta.gouv.fr',
    'developpement-durbale.gouv.fr',
    'sine-et-marne.gouv.fr',
    'sociale.gouv.fr',
    'develeoppement-durable.gouv.fr',
    'draaf.gouv.fr',
    'drets.gouv.fr',
    'ancli.gouv.fr',
    'finistrere.gouv.fr',
    'bourgogne.pref.gouv.fr',
    'ac-polynesie.pf',
    'ac-lille.fr',
    'ac-nantes.fr',
    'ac-martinique.fr',
    'ac-creteil.fr',
    'ac-toulouse.fr',
    'ac-amiensfr',
    'ac-amiens.fr',
    'ac-rennes.fr',
    'ac-strasbourg.fr',
    'ac-lyon.fr',
    'ac-versailles.fr',
    'ac-audit.fr',
    'ac-rouen.fr',
    'ac-reunion.fr',
    'ac-poitiers.fr',
    'ac-caen.fr',
    'ac-montpellier.fr',
    'ac-paris.fr',
    'ac-besancon.fr',
    'ac-nancy-metz.fr',
    'ac-aix-marseille.fr',
    'ac-grenoble.fr',
    'ac-corse.fr',
    'ac-nice.fr',
    'ac-orleans-tours.fr',
    'ac-guadeloupe.fr',
    'ac-reims.fr',
    'ac-mayotte.fr',
    'ac-clermont.fr',
    'ac-bordeaux.fr',
    'ac-limoges.fr',
    'ac-normandie.fr',
    'ac-dijon.fr',
    'ac-guyane.fr',
    'ac-transports.fr',
    'ac-arpajonnais.com',
    'ac-cned.fr',
    'ac-nettoyage.com',
    'ac-architectes.fr',
    'ac-ajaccio.corsica',
    'ac-noumea.nc',
    'ac-spm.fr',
    'ac-versailes.fr',
    'ac-polynesie.fr',
    'ac-experts.fr',
    'ac-creteil.com',
    'ac-smart-relocation.com',
    'ac-ec.pro',
    'ac-sas.fr',
    'ac-derma.de',
    'ac-or.com',
    'ac-baugeois.fr',
    'ac-5.ru',
    'ac-arles.fr',
    'ac-holding.net',
    'ac-mb.fr',
    'ac-wf.wf',
    'ac-brest-finistere.fr',
    'ac-leman.com',
    'ac-darboussier.fr',
    'ac-si.fr',
    'ac-bordeau.fr',
    'ac-gatinais.com',
    'ac-cheminots.fr',
    'ac-seyssinet.com',
    'ac-cannes.fr',
    'ac-prev.com',
    'ac-sologne.fr',
    'ac-rennes',
    'ac-courbevoie.com',
    'ac-ce.fr',
    'ac-architecte.fr',
    'ac-tions.org',
    'ac-pm.fr',
    'ac-avocats.com',
    'ac-talents-rh.com',
    'ac-louis.com',
    'ac-internet.fr',
    'ac-toulouse.com',
    'ac-escial.fr',
    'ac-environnement.com',
    'ac-academie.fr',
    'ac-poiters.fr',
    'ac-bordeux.fr',
    'ac-verseilles.fr',
    'ac-ais-marseille.fr',
    'ac-horizon.fr',
    'ac-bordeaux.ft',
    'ac-toulouses.fr',
    'ac-toulous.fr'
  ].freeze

  def self.check(email:)
    return { success: false } if email.blank?

    parsed_email = Mail::Address.new(EmailSanitizableConcern::EmailSanitizer.sanitize(email))
    return { success: false } if parsed_email.domain.blank?

    return { success: true } if KNOWN_DOMAINS.any? { _1 == parsed_email.domain }

    similar_domains = closest_domains(domain: parsed_email.domain)
    return { success: true } if similar_domains.empty?

    { success: true, suggestions: suggestions(parsed_email:, similar_domains:) }
  rescue Mail::Field::IncompleteParseError
    return { success: false }
  end

  private

  def self.closest_domains(domain:)
    KNOWN_DOMAINS.filter do |known_domain|
      close_by_distance_of(domain, known_domain, distance: 1) ||
      with_same_chars_and_close_by_distance_of(domain, known_domain, distance: 2)
    end
  end

  def self.close_by_distance_of(a, b, distance:)
    String::Similarity.levenshtein_distance(a, b) == distance
  end

  def self.with_same_chars_and_close_by_distance_of(a, b, distance:)
    close_by_distance_of(a, b, distance: 2) && a.chars.sort == b.chars.sort
  end

  def self.suggestions(parsed_email:, similar_domains:)
    similar_domains.map { Mail::Address.new("#{parsed_email.local}@#{_1}").to_s }
  end
end
