<script setup lang="ts">
import {
  onMounted,
  ref,
  reactive,
  computed,
  watch,
  Ref,
  onBeforeUnmount,
} from 'vue'
import { Pixihttp } from '../systems/http.ts'
import {
  Spritesheet,
  AnimatedSprite,
  Texture,
  Application,
  Sprite,
  Assets,
} from 'pixi.js'
import * as PIXI from 'pixi.js'
import liuxinPath from '@/assets/liuxin/liuxin.png'
import liuxinPathJS from '@/assets/liuxin/liuxin.json'
import housePath from '@/assets/house/house.png'
import housePathGIF from '@/assets/house/house.gif'
import housePathJS from '@/assets/house/house.json'
// 已有的状态
const checked_type = ref('1')
const model_id = ref('')
const canvasdomref = ref(null)
const selectedlist = ref<Array<any>>([])
// 使用 reactive 创建响应式数组
const stable_diffusion_xls = reactive<Array<any>>([])
const fluxs = reactive<Array<any>>([])
const selected = ref<Array<any>>([])
const msgtext = ref('Hello')
// 分页状态
const currentPage = ref(1)
const itemsPerPage = 50
const text = new PIXI.Text({
  text: msgtext.value,
  style: {
    fontFamily: 'Arial',
    fontSize: 50,
    fill: 0xff1010,
  },
})
// 监听 checked_type 变化，重置 currentPage
watch(checked_type, () => {
  currentPage.value = 1
})

// 计算总页数
const totalPages = computed(() => {
  const totalItems =
    checked_type.value === '1' ? stable_diffusion_xls.length : fluxs.length
  return Math.ceil(totalItems / itemsPerPage)
})

// 计算当前页显示的模型
const paginatedModels = computed(() => {
  const models = checked_type.value === '1' ? stable_diffusion_xls : fluxs
  const start = (currentPage.value - 1) * itemsPerPage
  const end = start + itemsPerPage
  return models.slice(start, end)
})

// 新增：画廊相关状态
const images = reactive<Array<string>>([])

const galleryCurrentPage = ref(1)
const galleryItemsPerPage = 12
let st = JSON.stringify({
  key: '',
  model_id: 'your_model_id',
  prompt:
    'ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner)), blue eyes, shaved side haircut, hyper detail, cinematic lighting, magic neon, dark red city, Canon EOS R3, nikon, f/1.4, ISO 200, 1/160s, 8K, RAW, unedited, symmetrical balance, in-frame, 8K',
  negative_prompt: '',
  width: '512',
  height: '512',
  samples: '1',
  num_inference_steps: '31',
  safety_checker: 'no',
  enhance_prompt: 'yes',
  seed: null,
  guidance_scale: 7.5,
  panorama: 'no',
  self_attention: 'no',
  upscale: 'no',
  embeddings_model: null,
  lora_model: null,
  tomesd: 'yes',
  clip_skip: '2',
  use_karras_sigmas: 'yes',
  vae: null,
  lora_strength: null,
  scheduler: 'UniPCMultistepScheduler',
  webhook: null,
  track_id: null,
})
const code_input_ = ref(st)
const ondraw = async () => {
  console.log(code_input_.value)
  console.log(formattedSelectedList.value)
  let arg = ''
  try {
    arg = JSON.parse(code_input_.value)
    // 如果解析成功，说明是合法的 JSON 字符串
    console.log('code_input_.value 是合法的 JSON 字符串。')
  } catch (e) {
    // 如果解析失败，说明不是合法的 JSON 字符串
    console.log('code_input_.value 不是合法的 JSON 字符串。')
    text.text = '输入参数不是合法的 JSON 字符串。'
    return
  }
  let list = formattedSelectedList.value

  // 使用扩展运算符合并所有子元素，并使用 filter() 方法去除空字符串
  let mergedList = [].concat(...list).filter((item) => item !== '')
  if (mergedList.length == 0) {
    text.text = '请先选择模型或输入模型id'
    return
  } else {
    //发起请求
    // 遍历并立即发起请求
    mergedList.forEach(async (modelId) => {
      arg.model_id = modelId
      arg.key = 'wHzwvPzl70HdTBIvLdzJZMxHrpdSWyA1ARVXVU5w9YQzMw9oO6WhiIlkpOUY'

      try {
        const rs = await Pixihttp.get_image(arg)
        if ((rs.data.status = 'success')) {
          rs.data.output.forEach((element) => {
            images.push(element)
          })
        }

        console.log(`请求结果 for model_id: ${modelId}`, rs)
      } catch (error) {
        console.error(`请求失败 for model_id: ${modelId}`, error)
      }
    })
  }
  // 打印合并后的列表和它的长度
  console.log(mergedList)
  console.log(mergedList.length)
}
// 计算画廊总页数
const galleryTotalPages = computed(() =>
  Math.ceil(images.length / galleryItemsPerPage)
)

// 计算当前页显示的图片
const paginatedGalleryImages = computed(() => {
  const start = (galleryCurrentPage.value - 1) * galleryItemsPerPage
  const end = start + galleryItemsPerPage
  return images.slice(start, end)
})

// 监听 galleryCurrentPage 变化，确保其不超过总页数
watch(galleryTotalPages, (newTotal) => {
  if (galleryCurrentPage.value > newTotal) {
    galleryCurrentPage.value = newTotal
  }
})

watch(msgtext, (newVal) => {
  if (text) {
    text.text = newVal
  }
})
// 创建一个计算属性，它基于selected和model_id的值
const formattedSelectedList = computed(() => {
  return [selected.value, model_id.value]
})
watch(formattedSelectedList, (newVal) => {
  text.text = '目前选择的模型：' + newVal
})
const dataLoaded = ref(false)
onMounted(async () => {
  try {
    const canvas = canvasdomref.value
    let width = window.screen.width
    let height = window.screen.height
    if (width > height) {
      console.log('横屏')
    } else {
      console.log('竖屏')
    }
    console.log('屏幕长宽:', width, height)
    let app = new Application()

    await app.init({
      resizeTo: window,
      backgroundAlpha: 0,
    })
    let canvasInfo = app.canvas

    const liuxintexture = await Assets.load(liuxinPath)
    const liuxinsheet = new Spritesheet(liuxintexture, liuxinPathJS)
    await liuxinsheet.parse()
    const liuxinsp = new AnimatedSprite(
      liuxinsheet.animations['9c0d85519fc29bd805102e958f2e83e5_wps图片']
    )
    liuxinsp.animationSpeed = 0.03
    liuxinsp.width = 800
    liuxinsp.height = 800
    liuxinsp.loop = true
    liuxinsp!.anchor.x = 0.5
    liuxinsp!.anchor.y = 0.5
    liuxinsp.gotoAndPlay(0)
    const housetexture = await Assets.load(housePath)
    const housesheet = new Spritesheet(housetexture, housePathJS)
    await housesheet.parse()
    const housesp = new AnimatedSprite(
      housesheet.animations['762064eed8a6bd88c0f3d583cd0cfe81_wps图片']
    )
    housesp.animationSpeed = 0.03
    housesp.width = 800
    housesp.height = 800
    housesp.loop = true
    housesp!.anchor.x = 0.5
    housesp!.anchor.y = 0.5
    housesp.gotoAndPlay(0)

    text.y = housesp.position.y + 250
    const container = new PIXI.Container()
    container.accessible = false
    container.x = app.screen.width / 2
    container.y = app.screen.height / 2
    container.addChild(liuxinsp)
    container.addChild(housesp)
    container.addChild(text)
    app.stage.addChild(container)
    // @ts-ignore
    canvas?.appendChild(canvasInfo)

    const httpdata = await Pixihttp.get_model_list()
    for (let entry of httpdata.data) {
      if (entry.model_category === 'stable_diffusion_xl') {
        stable_diffusion_xls.push(entry)
        msgtext.value = '正在加载SD-XL信息'
      } else if (entry.model_category === 'flux') {
        fluxs.push(entry)
        msgtext.value = '正在加载FLUX信息'
      }
    }
    msgtext.value = 'OK可以开始绘画！！'
    // 按 api_calls 降序排序 stable_diffusion_xls
    stable_diffusion_xls.sort((a, b) => b.api_calls - a.api_calls)

    // 按 api_calls 降序排序 fluxs
    fluxs.sort((a, b) => b.api_calls - a.api_calls)

    console.log('Stable Diffusion XL Models:', stable_diffusion_xls)
    console.log('Flux Models:', fluxs)
    container.scale.set(0.4)
    container.x = container.width
    container.y = 80
    dataLoaded.value = true
  } catch (error) {
    console.error('Failed to fetch model list:', error)
  }
})
// Add the onBeforeUnmount hook to clean up the Pixi.js application
onBeforeUnmount(() => {
  if (app) {
    // 停止渲染循环并销毁应用程序
    app.destroy(
      { removeView: true },
      { children: true, texture: true, textureSource: true, context: true }
    )
    app = null // Set to null to allow garbage collection
  }
})
</script>

<template>
  <div class="root">
    <div class="draw_stage" ref="canvasdomref"></div>
    <div v-if="dataLoaded" class="content">
      <van-row justify="center">
        <van-col :span="20">
          <div class="main-container">
            <!-- 标题部分 -->
            <van-row class="header" justify="center">
              <van-col>
                <h1 class="title">模型测试</h1>
              </van-col>
            </van-row>

            <!-- 模型类型选择 -->
            <van-row class="section" justify="center">
              <van-col :span="12">
                <div class="model-type">
                  <van-radio-group
                    v-model="checked_type"
                    direction="horizontal"
                  >
                    <van-radio name="1">SD-XL</van-radio>
                    <van-radio name="2">FLUX</van-radio>
                  </van-radio-group>
                </div>
              </van-col>
            </van-row>

            <!-- 模型ID输入 -->
            <van-row class="section" justify="center">
              <van-col :span="12">
                <div class="model-id">
                  <van-cell-group inset>
                    <van-field
                      v-model="model_id"
                      label="模型ID："
                      left-icon="smile-o"
                      right-icon="warning-o"
                      placeholder="输入模型ID"
                      clearable
                    />
                  </van-cell-group>
                </div>
              </van-col>
            </van-row>

            <!-- 模型列表和代码输入区域 -->
            <van-row class="section align-stretch" justify="center">
              <!-- 模型列表 -->
              <van-col :span="12" class="flex-item">
                <div class="model-list">
                  <v-container fluid>
                    <v-list lines="one" density="compact" max-height="300">
                      <v-list-item
                        v-for="item in paginatedModels"
                        :key="item.model_id"
                        ><v-checkbox
                          class="my-custom-checkbox"
                          color="red"
                          v-model="selected"
                          :label="
                            item.model_name + ' 调用次数： ' + item.api_calls
                          "
                          :value="item.model_id"
                        >
                        </v-checkbox>
                      </v-list-item>
                    </v-list>
                  </v-container>
                  <v-pagination
                    v-model="currentPage"
                    :length="totalPages"
                    class="pagination"
                  ></v-pagination>
                </div>
              </van-col>

              <!-- 代码输入 -->
              <van-col :span="12" class="flex-item">
                <div class="code_input">
                  <v-container>
                    <v-textarea
                      row-height="15"
                      bg-color="amber-lighten-4"
                      color="orange orange-darken-4"
                      label="代码输入"
                      rows="10"
                      v-model="code_input_"
                      placeholder='{
  "key": "",
  "model_id": "your_model_id",
  "prompt": "ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner)), blue eyes, shaved side haircut, hyper detail, cinematic lighting, magic neon, dark red city, Canon EOS R3, nikon, f/1.4, ISO 200, 1/160s, 8K, RAW, unedited, symmetrical balance, in-frame, 8K",
  "negative_prompt": "",
  "width": "512",
  "height": "512",
  "samples": "1",
  "num_inference_steps": "31",
  "safety_checker": "no",
  "enhance_prompt": "yes",
  "seed": null,
  "guidance_scale": 7.5,
  "panorama": "no",
  "self_attention": "no",
  "upscale": "no",
  "embeddings_model": null,
  "lora_model": null,
  "tomesd": "yes",
  "clip_skip": "2",
  "use_karras_sigmas": "yes",
  "vae": null,
  "lora_strength": null,
  "scheduler": "UniPCMultistepScheduler",
  "webhook": null,
  "track_id": null
}'
                      auto-grow
                    ></v-textarea>
                  </v-container>
                  <v-btn block @click="ondraw">开始绘图</v-btn>
                </div>
              </van-col>
            </van-row>

            <!-- 新增：画廊部分 -->
            <van-row class="draw" justify="center">
              <van-col :span="24">
                <div class="gallery">
                  <h2 class="gallery-title">画廊</h2>
                  <van-row justify="start" wrap>
                    <van-col
                      v-for="(image, index) in paginatedGalleryImages"
                      :key="index"
                      :span="4"
                      class="gallery-item"
                    >
                      <img
                        :src="image"
                        alt="Gallery Image"
                        class="gallery-image"
                      />
                    </van-col>
                  </van-row>
                  <v-pagination
                    v-model="galleryCurrentPage"
                    :length="galleryTotalPages"
                    class="pagination"
                  ></v-pagination>
                </div>
              </van-col>
            </van-row>
          </div>
        </van-col>
      </van-row>
    </div>
  </div>
</template>

<style scoped>
/* .root {
  background-color: #ffffff00;
  padding: 20px 0;
  min-height: 100vh;
} */
.draw_stage {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  pointer-events: none;
}
.main-container {
  background-color: #ffffff00;
  padding: 30px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.header {
  margin-bottom: 30px;
}

.title {
  font-size: 24px;
  font-weight: 600;
  text-align: center;
  color: #333333;
}

.section {
  margin-bottom: 25px;
}

.align-stretch {
  display: flex;
  align-items: stretch;
}

.flex-item {
  display: flex;
}

.model-type {
  display: flex;
  justify-content: center;
}

.model-id .van-field__control {
  padding-left: 10px;
}

.model-list,
.code_input {
  background-color: #fafafa;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #eaeaea;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.gallery {
  padding: 15px;
  border-radius: 6px;

  flex: 1;
  display: flex;
  flex-direction: column;
}
.draw {
  background-color: #fafafa;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #eaeaea;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.v-list-item {
  padding: 10px 15px;
  border-bottom: 1px solid #eaeaea;
  flex: none;
}

.v-list-item:last-child {
  border-bottom: none;
}

.v-list-item__title {
  font-weight: 500;
  color: #555555;
}

.v-list-item__subtitle {
  color: #888888;
  font-size: 14px;
}

.pagination {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  flex-shrink: 0;
}

/* 画廊样式 */
.gallery {
  padding: 20px 0;
}

.gallery-title {
  text-align: center;
  margin-bottom: 20px;
  font-size: 20px;
  color: #333333;
}

.gallery-item {
  padding: 10px;
}

.gallery-image {
  width: 100%;
  height: auto;
  border-radius: 4px;
  object-fit: cover;
}
</style>
帮我稍微修改一下 在画廊里每个图片下面要标注 arg.model_id = modelId 这个modelId 表明图片来自哪个模型id