<template>
    <div class="flex flex-col gap-5 mx-auto p-2 w-full max-w-md">
        <div class="mb-5">
            <form @submit.prevent="submitLedenlijst" class="flex flex-col">
                <input required="true" @change="handleFileChanged" accept=".csv" class="my-2" type="file">
                <span class="text-sm"><i>Met de volgende kolommen: Relatiecode, Volledige naam(1), Roepnaam, E-mail, 2e E-mail, Verenigingssporten, Diploma</i></span>
                <button :disabled="disableButtons" class="btn mx-auto mt-2">Publish Ledenlijst</button>
            </form>
        </div>
        <div class="flex flex-col gap-3">
            <input v-model="searchTerm" class="input mb-2 font-bold" type="search" placeholder="Search">
            <div v-for="lid in filteredLedenlijst" :key="lid.relatiecode">
                <div class="item container flex flex-wrap">
                    <b class="w-24">{{ lid.relatiecode }}</b> {{ lid.fullName }}
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { doc, getDocs, collection, writeBatch, runTransaction } from "firebase/firestore"; 
import { useToast } from 'vue-toastification'

definePageMeta({
    title: 'Ledenlijst',
    key: 'back'
})

const { db, ledenlijst, users } = inject('firebase')

const toast = useToast()

const file = ref(null)
const disableButtons = ref(false)
const searchTerm = ref('')
const newLedenlijst = ref([])

onMounted(async () => {
  if (!ledenlijst.value.length) {
    try {
      const querySnapshot = await getDocs(collection(db, "ledenlijst"));
      querySnapshot.forEach((doc) => {
        ledenlijst.value.push(doc.data())
      });
    } catch (e) {
      console.log(e)
    }

    ledenlijst.value.sort((a, b) => a.fullName.localeCompare(b.fullName))
  }
})

const filteredLedenlijst = computed(() => {
  return ledenlijst.value.filter(lid => lid.fullName.toLowerCase().includes(searchTerm.value.toLowerCase()))
})

const handleFileChanged = (event) => {
  const target = event.target;

  if (target && target.files) {
    file.value = target.files[0];
  }
}

const submitLedenlijst = () => {
  disableButtons.value = true

  let reader = new FileReader()

  reader.onload = function() {
    csvToJson(reader.result);
  };

  reader.onerror = function() {
    console.log(reader.error);
  };

  reader.readAsText(file.value)
}

const csvToJson = (csv) => {
  let arr = csv.split('\n');

  var result = [];
  var headers = arr[0].split(';');
  for(var i = 1; i < arr.length; i++) {
    var data = arr[i].split(';');
    var obj = {};
    for(var j = 0; j < data.length; j++) {
      obj[headers[j].trim()] = data[j].trim();
    }
    result.push(obj);
  }

  if (!Object.hasOwn(result[0], 'Relatiecode') || !Object.hasOwn(result[0], 'Volledige naam (1)') || !Object.hasOwn(result[0], 'E-mail') || !Object.hasOwn(result[0], '2e E-mail') || !Object.hasOwn(result[0], 'Verenigingssporten') || !Object.hasOwn(result[0], 'Diploma dropdown 1')) return toast.error('Missing properties')

  newLedenlijst.value = []

  for (let i in result) {
    let groups = []
    let correctGroups = null 
    if (!result[i].Relatiecode) break; 

    if (result[i].Verenigingssporten.includes(',')) correctGroups = result[i].Verenigingssporten.split(',')    
    else correctGroups = [result[i].Verenigingssporten] 
    
    correctGroups.forEach(group => {
      const x = group.split(' - ')

      if (x[2] === 'Week') groups.push('Vrijdag') 
      else if (x[2] === 'Zaterdag' && x[1] !== 'Wedstrijd') groups.push('Zaterdag')

      groups.push(x[1])
    })

    if (groups[2] === 'Week') groups[2] = 'Vrijdag'
    
    newLedenlijst.value.push({ relatiecode: result[i].Relatiecode, fullName: result[i]['Volledige naam (1)'], email: [result[i]['E-mail'], result[i]['2e E-mail']], groups: [...new Set(groups)], diploma: result[i]['Diploma dropdown 1'] })
  }
  uploadLedenlijst()
}

const uploadLedenlijst = async () => {
  try {
    const batch = writeBatch(db)

    newLedenlijst.value.forEach(lid => {
      const docRef = doc(db, "ledenlijst", lid.relatiecode)

      const exists = ledenlijst.value.filter(a => a.relatiecode === lid.relatiecode).length > 1

      if (!exists) {
        return batch.set(docRef, lid);
      }
      
      batch.update(docRef, { fullName: lid.relatiecode, email: lid.email, groups: lid.groups, diploma: lid.diploma})
    })

    const deleteLeden = ledenlijst.value.filter(a => newLedenlijst.value.map(x => x.relatiecode).indexOf(a.relatiecode) === -1)
    
    deleteLeden.forEach(lid => {
      const docRef = doc(db, "ledenlijst", lid.relatiecode)

      batch.delete(docRef)
    })

    await batch.commit();

    toast.success('Published ledenlijst')
  } catch (e) {
    toast.error("Error updating ledenlijst");
    console.log(e)
  }

  ledenlijst.value = newLedenlijst.value
  
  updateUsers()
}


const updateUsers = async () => {
  try {
    const querySnapshot = await getDocs(collection(db, "users"));
    querySnapshot.forEach((doc) => {
      const data = doc.data()
      data.id = doc.id
      users.value.push(data)

    });
  } catch (e) {
    console.log(e)

    toast.error('Error getting users')
  }
  
  const batch = writeBatch(db);

  users.value.forEach(user => {
    const lid = ledenlijst.value.filter(a => a.email.includes(user.email))
    const newRelatiecodes = lid.map(a => a.relatiecode)
    
    user.allRelatiecodes = newRelatiecodes
    user.relatiecodes.forEach((relatiecode, index) => {
      if (!newRelatiecodes.includes(relatiecode)) { user.relatiecodes.splice(index, 1); console.log('removed item', relatiecode)}
    })

    const userRef = doc(db, "users", user.id)    
    batch.update(userRef, user)
  })
  
  await batch.commit();

  disableButtons.value = false
}
</script>
