<script setup lang="ts">
import { Settings } from '@vicons/carbon'
import { Icon } from '@vicons/utils'
import { NButton, type UploadFileInfo, useMessage } from 'naive-ui'
import { NCard, NFlex, NInput, NModal, NSpace, NText, NUpload, NUploadDragger } from 'naive-ui'
import { ref } from 'vue'
import { useRoute } from 'vue-router'

import { getAuthClient } from '@/api/auth_client'
import type { Place, Scenario } from '@/api/generated/crabs/evening_detective_server'
import HeaderMenu from '@/components/HeaderMenu.vue'
import PlaceBlock from '@/components/PlaceBlock.vue'
import router from '@/router'

const client = getAuthClient()
const route = useRoute()
const scenarioId = route.params.id

const showSettingsScenarioModal = ref(false)
const deletedScenarioName = ref('')

const message = useMessage()

const fileList = ref<UploadFileInfo[]>([])

const scenario = ref<Scenario>({
  id: undefined,
  name: undefined,
  story: undefined,
  author: undefined,
  updatedAt: undefined,
  createdAt: undefined,
  publishedAt: undefined,
})

const newPlace = ref<Place>({
  code: undefined,
  name: undefined,
  text: undefined,
  image: undefined,
  hidden: undefined,
  applications: undefined,
  doors: undefined,
  keys: undefined,
  mode: 'mini-add',
})

async function getScenario(id: number) {
  const res = await client.GetScenario({ id: id })
  if (res.error != '') {
    message.error(res.error!)
    return
  }
  scenario.value = res.scenario!
  scenario.value.story?.places?.forEach((item) => {
    item.oldCode = item.code
    item.mode = 'show-editor'
  })
}
getScenario(Number(scenarioId))

async function deleteScenario(id: number) {
  const res = await client.DeleteScenario({ id: id })
  if (res.error != '') {
    message.error(res.error!)
    return
  }
  router.push('/scenarios')
}

async function updateScenario() {
  const file = fileList.value[0].file
  if (!file) return

  // Читаем как ArrayBuffer
  const arrayBuffer = await file.arrayBuffer()
  const bytes = new Uint8Array(arrayBuffer)

  const resUploadFile = await client.UploadFile({
    filename: 'scenarios_' + scenario.value.id + '_' + file.name,
    data: uint8ToBase64(bytes),
  })
  if (resUploadFile.error != '') {
    message.error(resUploadFile.error!)
    return
  }

  const res = await client.UpdateScenario({
    id: scenario.value.id,
    name: scenario.value.name,
    description: scenario.value.description,
    image: resUploadFile.filename,
  })
  if (res.error != '') {
    message.error(res.error!)
    return
  }
  await getScenario(Number(scenarioId))
  showSettingsScenarioModal.value = false
}

function uint8ToBase64(uint8Array: Uint8Array) {
  // Преобразуем Uint8Array в двоичную строку
  const binaryString = String.fromCharCode(...uint8Array)
  // Кодируем в Base64
  return btoa(binaryString)
}

async function addPlace() {
  const res = await client.AddScenarioPlace({
    id: scenario.value.id,
    place: newPlace.value,
  })
  if (res.error != '') {
    message.error(res.error!)
    return
  }
  await getScenario(Number(scenarioId))

  newPlace.value = {
    code: undefined,
    name: undefined,
    text: undefined,
    image: undefined,
    hidden: undefined,
    applications: undefined,
    doors: undefined,
    keys: undefined,
  }
}

async function collapseAddPlace(place: Place) {
  place.mode = 'mini-add'
}

async function cancelUpdatePlace(place: Place) {
  await getScenario(Number(scenarioId))

  place.mode = 'show-editor'
}

async function updatePlace(place: Place) {
  const res = await client.UpdateScenarioPlace({
    id: scenario.value.id,
    code: place.oldCode,
    place: place,
  })
  if (res.error != '') {
    message.error(res.error!)
    return
  }
  await getScenario(Number(scenarioId))

  place.mode = 'show-editor'
}

async function deletePlace(place: Place) {
  const res = await client.DeleteScenarioPlace({
    id: scenario.value.id,
    code: place.oldCode,
  })
  if (res.error != '') {
    message.error(res.error!)
    return
  }
  await getScenario(Number(scenarioId))
}
</script>

<template>
  <HeaderMenu :add-logout="true" active="scenarios" />

  <div class="center-block-custom-big content-block">
    <div class="places-container">
      <div class="settings-block">
        <n-button quaternary @click="showSettingsScenarioModal = true" class="settings-button">
          <Icon class="settings-icon">
            <Settings />
          </Icon>
          Настройки
        </n-button>
      </div>

      <PlaceBlock :place="newPlace" v-model:mode="newPlace.mode">
        <n-flex justify="end">
          <n-button @click="collapseAddPlace(newPlace)">Отмена</n-button>
          <n-button @click="addPlace()" :disabled="!newPlace.code">Добавить точку</n-button>
        </n-flex>
      </PlaceBlock>

      <PlaceBlock
        :place="place"
        v-model:mode="place.mode"
        v-for="place in scenario.story?.places"
        v-bind:key="place.code"
      >
        <n-flex justify="end">
          <n-button @click="deletePlace(place)" type="error" ghost>Удалить</n-button>
          <n-button @click="cancelUpdatePlace(place)">Отмена</n-button>
          <n-button @click="updatePlace(place)">Сохранить</n-button>
        </n-flex>
      </PlaceBlock>
    </div>
  </div>

  <!-- Окно настроек сценария -->
  <n-modal v-model:show="showSettingsScenarioModal">
    <n-card
      style="width: 600px"
      title="Настройки сценария"
      :bordered="false"
      size="huge"
      role="dialog"
      aria-modal="true"
    >
      <template #header-extra>
        <n-button @click="showSettingsScenarioModal = false"> x </n-button>
      </template>
      <n-space vertical>
        <p>Название</p>
        <n-input
          v-model:value="scenario.name"
          type="text"
          placeholder='Дело №0 "Следствие ведут овечки"'
        />

        <p class="settings-header">Описание</p>
        <n-input
          v-model:value="scenario.description"
          type="textarea"
          placeholder="Убийство пастуха..."
        />

        <p class="settings-header">Картинка</p>
        <n-input
          v-model:value="scenario.image"
          type="text"
          placeholder="default_scenario.png"
          disabled
        />
        <n-upload multiple directory-dnd :max="1" v-model:file-list="fileList">
          <n-upload-dragger>
            <n-text style="font-size: 16px">
              Щелкните или перетащите файл в эту область для загрузки
            </n-text>
          </n-upload-dragger>
        </n-upload>

        <n-button @click="updateScenario()" ghost> Сохранить изменения </n-button>

        <hr class="settings-hr" />

        <p>
          Введите название сценария
          <n-text class="name-text" strong>{{ scenario.name }}</n-text> чтобы удалить его
        </p>
        <n-input
          v-model:value="deletedScenarioName"
          type="text"
          placeholder='Дело №0 "Следствие ведут овечки"'
        />
        <n-button
          @click="deleteScenario(scenario.id!)"
          type="error"
          ghost
          :disabled="deletedScenarioName != scenario.name"
        >
          Удалить сценарий
        </n-button>
      </n-space>
      <template #footer> </template>
    </n-card>
  </n-modal>
</template>

<style scoped>
.settings-block {
  height: 40px;

  /* background-color: brown; */
}

.settings-button {
  float: right;
}

.settings-icon {
  width: 20px;
}

.name-text {
  padding: 3px;
  border-radius: 3px;
  background-color: rgb(255 255 255 / 10%);
}

.settings-header {
  margin-top: 20px;
}

.settings-hr {
  margin: 20px 0;
}

.places-container {
  display: flex;
  flex-flow: column nowrap;
  overflow-y: auto;
  padding: 20px 0;
  height: calc(100vh - 150px);

  /* border: 1px solid red; */
}

@media (width >= 1024px) {
  .places-container {
    padding: 20px 250px;
    height: calc(100vh - 70px);
  }
}
</style>
