import { defineStore } from 'pinia'
// import REST from '@api/rest-axios'
// import JSONAPI from '@api/json-axios'
import { print } from 'graphql/language/printer'
import gql from 'graphql-tag'



// import REST from '@api/rest-axios'
import GQL from '@api/graphql-axios'
// import JSONAPI from '@api/json-axios'

import ConcernementFields from '@api/gql/concernement.fragment.gql'
// import EntityFields from '@api/gql/entitydef.fragment.gql'

export const ConcernementsStore = defineStore({
  id: 'concernements',
  state: () => ({
    map_mode: null,
    concernements: [],
    concernementsByID: {},
    allEntitesById: {},
    allBesoinsById: {},
    allSuperpositions: [],
    allSuperpositions_bycids: {},
    allSuperpositions_clustered: [],
    allMapItems_byid: {},
    allProximites: [],
    opened_concernement: false,
    opened_entite_id: null,
    opened_recit: false,
    recit_plyr_player: null,
    ct_concernement: {},
    ct_entite: {},
    ct_cercle_politique: {},
    p_groupes_interets: {},
    p_reception_et_traitement: {},
    p_mise_en_oeuvre_decision: {},
    p_reception_application_decision: {},
    concernements_loaded: false,
    detailsZoomValue: 1,
  }),
  getters: {
    
  },
  actions: {
    setMapMode(mode) {
      console.log(`set map_mode ${mode}`);
      // mode can be : terraindevie, proximite, superposition, puissancedagir, action, doleancer
      this.map_mode = mode;
    },
    loadConcernements () {
      console.log('concernements store loadConcernements');
      return new Promise((resolve, reject) => {
        const ast = gql`{
          allconcernements {
            ...ConcernementFields
          }
        }
        ${ConcernementFields}
        `
        // console.log('ast', ast);
        GQL.post('', { query: print(ast) })
          .then(({ data : { data  : { allconcernements } } }) => {
            console.log('loadconcernements all loaded', allconcernements)
            this.concernements = [];
            // parse concernements
            let temp_allSuperpositions = [];
            allconcernements.forEach(concernement => {
              concernement.visible = true;

              concernement.entites_byid = {};
              concernement.entitesagissantes_byid = {};
              concernement.has_proximites = false;
              concernement.has_superpositions = false;
              concernement.has_agissantes = false;
              // var entites_temp = concernement.entites; // record a temp entites liste
              // concernement.entites = []; // erase the concernement.entite array as we want to keep only visible entites
              concernement.entites.forEach(entite => {
                if (entite.entite) { // entite.entite may be null because of workflow confidentiality
                  concernement.entites_byid[entite.entite.id] = entite;
                  // record entite agissante
                  if (entite.entite.agissante) {
                    concernement.entitesagissantes_byid[entite.entite.id] = entite;
                    concernement.has_agissantes = true;
                  }
                  // record a flat list of all entités of all concernement for map-popup
                  this.allEntitesById[entite.entite.id] = entite;
                  this.allEntitesById[entite.entite.id].cid = concernement.id;
                  // concernement.entites.push(entite); // fill the entites array with visible entite only

                  // PROXIMITES
                  if (entite.entite.proximite.length) {
                    console.log("proximite", entite.entite.proximite);
                    concernement.has_proximites = true;
                  }

                  // SUPERPOSITIONS
                  if (entite.entite.superposition.length) {
                    // create properties for later
                    concernement.superpositions = {};
                    concernement.superposition_constraints_id = {};
                    concernement.all_superposed_concernements_id = [];
                    concernement.superposed_mapitem_id_by_mapitem_id = {};

                    entite.entite.superposition.forEach(entite_superpose => {
                      // console.log(`superposition eid:${entite.entite.id}, teid:${entite_superpose.id}`);
                      let already_recorded = false;
                      // loop through all already recorded superposition to complete the array instead of create duplicates
                      // TODO check if target cid and eid are accessible before recording the superposition
                      // check if half of the superpositions is already recorded, if yes complete it (add the missing concernement id)
                      for(let superposition of temp_allSuperpositions) { 
                        for(let superposition_item of superposition) {
                          if (superposition_item.eid === entite.entite.id && !superposition_item.cid) {
                            // console.log(`already_recorded, eid:${entite.entite.id}, teid:${entite_superpose.id}`, entite.entite.title);
                            already_recorded = true;
                            superposition_item.cid = concernement.id;
                            break;
                          }
                        }
                        if (already_recorded) {
                          break;
                        }
                      }
                      // if not already recorded, add it to the array. It is incomplete has it's missing one concernement id wich will be filled in next loops
                      if (!already_recorded) {
                        // console.log(`NOT already_recorded, eid:${entite.entite.id}, teid:${entite_superpose.id}`, entite.entite.title);
                        let s = [
                          { 
                            cid: concernement.id, 
                            eid: entite.entite.id
                          },
                          {
                            cid: null,
                            eid: entite_superpose.id
                          }
                        ];
                        // concernement.superpositions.push(s); 
                        temp_allSuperpositions.push(s);

                      }
                    })
                  }

                }
              });

              
              // revisions
              concernement.active_revision = concernement.revision_id;
              concernement.revisions_byid = {};
              concernement.revisions.forEach(rev => {
                concernement.revisions_byid[rev.revision_id] = rev;
              });

              // puissance d'agir
              concernement.has_puissancedagir = concernement.besoins.length ? true : false;
              concernement.besoins.forEach(besoin => {
                this.allBesoinsById[besoin.id] = besoin;
              });

              // doleance
              concernement.has_doleance = concernement.doleances.length ? true : false;
              if (concernement.has_doleance) {
                console.log('concernement has doleance', concernement.doleances);
                concernement.opened_doleance = {
                  id: concernement.doleances[0].id
                };
              }
              
              // recit
              concernement.has_recit = concernement.recit !== null;

              // common
              this.concernements.push(concernement);
              this.concernementsByID[concernement.id] = concernement;

            }); // end of concernements loop
            console.log('temp_allSuperpositions', temp_allSuperpositions);

            // cleaning superpositions, removing all incomplète onces
            temp_allSuperpositions.forEach(s => {
              if (s[0] && s[0].cid && s[0].eid && s[1] && s[1].cid && s[1].eid) {
                this.allSuperpositions.push(s);
                this.concernementsByID[s[0].cid].has_superpositions = true;
                this.concernementsByID[s[1].cid].has_superpositions = true;
              }
            });
            console.log('this.allSuperpositions', this.allSuperpositions);


            // get superpositions by cluster
            for(let superpos_to_record of this.allSuperpositions){
              let recorded = false;
              // console.log('-- -- --');
              // console.log(`superpos_to_record : ${superpos_to_record[0].cid}-${superpos_to_record[0].eid}, ${superpos_to_record[1].cid}-${superpos_to_record[1].eid}`);
              // loop through alredy recorded clusters
              for(let [cluster_index, superpo_cluster] of this.allSuperpositions_clustered.entries()){
                // console.log('cluster_index', cluster_index);
                // for each cluster loop throug each superposition
                in_cluster_loop:{
                  for(let s of superpo_cluster){
                    // console.log(`s : ${s.cid}-${s.eid}`);
                    // loop through each cid_eid couple of superpo to be recorded
                    for(let i = 0; i <= 1; i++){
                      // if one couple already recorded in the cluster, add the other one to the same cluster
                      if (superpos_to_record[i].cid === s.cid && superpos_to_record[i].eid === s.eid){
                        // console.log('-- recorded');
                        let j = i === 0 ? 1 : 0;
                        // add the right item to the cluster
                        this.allSuperpositions_clustered[cluster_index].push(superpos_to_record[j]);
                        // record the superposition on the concernement BY cluster index
                        // console.log(`superpos_to_record[j].cid:${superpos_to_record[j].cid}`);
                        // console.log('concernement', this.concernementsByID[superpos_to_record[j].cid]);
                        // create array if not already exists
                        if(typeof this.concernementsByID[superpos_to_record[j].cid].superpositions[cluster_index] === 'undefined'){
                          this.concernementsByID[superpos_to_record[j].cid].superpositions[cluster_index] = [superpos_to_record];
                        }else{
                          this.concernementsByID[superpos_to_record[j].cid].superpositions[cluster_index].push(superpos_to_record);
                        }
                        recorded = true;
                        break in_cluster_loop;
                      }
                    }
                  }
                }
              }

              if(!recorded){
                // console.log('-- not recorded');
                // create cluster and fill it it with first couple
                this.allSuperpositions_clustered.push(superpos_to_record);
                // record superposition on each concernement of each couple member BY cluster index
                for( let i=0; i <= 1; i++){
                  this.concernementsByID[superpos_to_record[i].cid].superpositions[this.allSuperpositions_clustered.length-1] = [superpos_to_record];
                  // console.log(`concernement ${superpos_to_record[i].cid} superposition by cluster index`,this.concernementsByID[superpos_to_record[i].cid].superpositions);
                }
              }
            }
            console.log('this.allSuperpositions_clustered', this.allSuperpositions_clustered);


            this.concernements_loaded = true;
          })
          .catch(error => {
            console.warn('Issue with loadConcernements', error)
            Promise.reject(error)
          })
      })
    },
    reloadConcernements () {
      console.log('reloadConcernements');
      // reset the arrays
      this.concernements = [];
      this.concernementsByID = {};
      this.concernements_loaded = false;
      this.loadConcernements();
    },
    loadContentTypeDefinition () {
      const body = {
        query: `
          query EntityDef($type: String!, $bundle: String!){
            entitydef(type: $type, bundle: $bundle) {
              fields {
                type
                field_name
                label
                description
              }
            }
          }`,
        variables: {}
      } 

      // concernement
      body.variables = { type: 'node', bundle: 'concernement' } 
      GQL.post('', body)
        .then(({ data: { data: { entitydef }}}) => {
          // console.log('loadContentTypeDefinition entitydef', entitydef);
          entitydef.fields.forEach(field => {
            this.ct_concernement[field.field_name] = field;
          });
          console.log('loadContentTypeDefinition entitydef concernement', this.ct_concernement);
          
        })

      // entite
      body.variables = { type: 'node', bundle: 'entite' } 
      GQL.post('', body)
        .then(({ data: { data: { entitydef }}}) => {
          // console.log('loadContentTypeDefinition entitydef', entitydef);
          entitydef.fields.forEach(field => {
            this.ct_entite[field.field_name] = field;
          });
          console.log('loadContentTypeDefinition entitydef entite', this.ct_entite);
          
        })

      // cercle_politique
      body.variables = { type: 'node', bundle: 'cercle_politique' } 
      GQL.post('', body)
        .then(({ data: { data: { entitydef }}}) => {
          // console.log('loadContentTypeDefinition entitydef', entitydef);
          entitydef.fields.forEach(field => {
            this.ct_cercle_politique[field.field_name] = field;
          });
          console.log('loadContentTypeDefinition entitydef cercle_politique', this.ct_cercle_politique);
          
        })

      // paragraphe groupes_interets
      body.variables = { type: 'paragraph', bundle: 'groupes_interets' } 
      GQL.post('', body)
        .then(({ data: { data: { entitydef }}}) => {
          // console.log('loadContentTypeDefinition entitydef', entitydef);
          entitydef.fields.forEach(field => {
            this.p_groupes_interets[field.field_name] = field;
          });
          console.log('loadContentTypeDefinition entitydef p_groupes_interets', this.p_groupes_interets);
          
        })

      // paragraphe reception_et_traitement
      body.variables = { type: 'paragraph', bundle: 'reception_et_traitement' } 
      GQL.post('', body)
        .then(({ data: { data: { entitydef }}}) => {
          // console.log('loadContentTypeDefinition entitydef', entitydef);
          entitydef.fields.forEach(field => {
            this.p_reception_et_traitement[field.field_name] = field;
          });
          console.log('loadContentTypeDefinition entitydef p_reception_et_traitement', this.p_reception_et_traitement);
          
        })

      // paragraphe mise_en_oeuvre_decision
      body.variables = { type: 'paragraph', bundle: 'mise_en_oeuvre_decision' } 
      GQL.post('', body)
        .then(({ data: { data: { entitydef }}}) => {
          // console.log('loadContentTypeDefinition entitydef', entitydef);
          entitydef.fields.forEach(field => {
            this.p_mise_en_oeuvre_decision[field.field_name] = field;
          });
          console.log('loadContentTypeDefinition entitydef p_mise_en_oeuvre_decision', this.p_mise_en_oeuvre_decision);
          
        })

      // paragraphe reception_application_decision
      body.variables = { type: 'paragraph', bundle: 'reception_application_decision' } 
      GQL.post('', body)
        .then(({ data: { data: { entitydef }}}) => {
          // console.log('loadContentTypeDefinition entitydef', entitydef);
          entitydef.fields.forEach(field => {
            this.p_reception_application_decision[field.field_name] = field;
          });
          console.log('loadContentTypeDefinition entitydef p_reception_application_decision', this.p_reception_application_decision);
          
        })

    },
    hideShowConcernement (id, state) {
      // console.log(`disableConcernement id: ${id}`);
      this.concernements.forEach((c, i) => {
        if (c.id === id) {
          this.concernements[i].visible = this.concernementsByID[id].visible = state;  
        }
      })
    },
    openCloseConcernements (cid, id) {
      console.log(`openCloseConcernements cid: ${cid}, id: ${id}`);
      var state;
      let mapitem_id = id ? id : cid;
      this.opened_concernement = null;
      this.opened_recit = null;
      this.concernements.forEach((c, i) => {
        state = cid === c.id;
        // console.log(`openCloseConcernements foreach id: ${id}, c.id: ${c.id}, state: ${state}`, id, c.id);
        c.opened = this.concernements[i].opened = this.concernementsByID[c.id].opened = state;
        if (state) {
          this.opened_concernement = c;
          this.opened_concernement.opened_mapitem_id = mapitem_id;
          if (c.has_recit && this.map_mode === "terraindevie") {
            this.opened_recit = c.recit;
          }
          // console.log('openCloseConcernements', this.opened_concernement.opened);
        }
      });
    },
    resetConcernementOpened () {
      this.opened_concernement = null;
      this.openCloseConcernements();
    },
    // setConcernementScale(cid, scale){
    //   console.log(`setConcernementScale ${cid} ${scale}`);
    //   this.concernementsByID[cid].scale = scale;
    // },
    setOpenedEntiteId(id){
      this.opened_entite_id = id;
    },
    setBesoinPaperId(paper_id, cid, bid, rid){
      // this.concernements.forEach((c, i) => {
      //   if(c.id === cid){
          this.concernementsByID[cid].besoins.forEach((b,j) => {
            if(b.id === bid) {
              if (!rid) {
                // this.concernements[i].besoins[j].paper_id = this.concernementsByID[cid].besoins[j].paper_id = paper_id;
                this.concernementsByID[cid].besoins[j].paper_id = paper_id;
                
              } else {
                this.concernementsByID[cid].besoins[j].reponses.forEach((r,k) => {
                  if (r.id === rid) {
                    // this.concernements[i].besoins[j].reponses[k].paper_id = this.concernementsByID[cid].besoins[j].reponses[k].paper_id = paper_id;
                    this.concernementsByID[cid].besoins[j].reponses[k].paper_id = paper_id;
                  }
                })
              }
            }
          })
      //   }
      // })
    },
    setOpenedDoleance(cid, did){
      console.log(`setOpenedDoleance(${cid}, ${did})`, cid, did);
      this.concernementsByID[cid].opened_doleance = {id: did};
      // console.log('this.opened_concernement.opened_doleance', this.opened_concernement.opened_doleance);
    },
    setOpenedDoleanceField(cid, did, field, index){
      console.log(`setOpenedDoleanceField cid, did, field, index`, cid, did, field, index);
      this.concernementsByID[cid].opened_doleance = {
        cid: cid,
        id: did,
        field: field,
        field_index: index
      };
    },
    setOpenedRecit (recit) {
      this.opened_recit = recit;
    },
    setRecitPlayer (player) {
      console.log('concernement store setRecitPlayer', player);
      this.recit_plyr_player = player;
    },
    setActiveRevision (cid, rid) {
      // console.log(`setActiveRevision, cid:${cid}, rid:${rid}`);
      this.concernementsByID[cid].active_revision = rid;
    },
    setDetailsZoomValue (z) {
      console.log(`concernement store setDetailsZoomValue ${z}`);
      this.detailsZoomValue = z;
    }

  }
})