<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)
})

// 新增：画廊相关状态
// 修改后的声明
interface ImageEntry {
  modelId: string
  url: string
}

const images = reactive<Array<ImageEntry>>([])

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)
async function pollForImage(rs: any) {
  try {
    let modelId = rs.data.meta.model_id
    const id = rs.data.id
    const key = 'wHzwvPzl70HdTBIvLdzJZMxHrpdSWyA1ARVXVU5w9YQzMw9oO6WhiIlkpOUY'
    const response = await Pixihttp.get_output_image({
      request_id: id,
      key: key,
    })
    if (response.data.status === 'success') {
      console.log(response.data)
      if (response.data.output && response.data.output.length > 0) {
        response.data.output.forEach((url: string) => {
          images.push({ modelId, url })
        })
      }
    } else if (response.data.status === 'failed') {
      console.error('模型生成失败:', modelId)
      text.text = `模型 ${modelId} 的图像生成失败`
    } else {
      // 如果状态是 'processing'，等待一段时间后再次检查
      setTimeout(() => {
        pollForImage(rs)
      }, 3000) // 每隔 3 秒轮询一次
    }
  } catch (error) {
    console.error('轮询图像时出错:', error)
  }
}
const ondraw = async () => {
  console.log(code_input_.value)
  console.log(formattedSelectedList.value)
  let arg: any = ''
  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

  // 合并并过滤空字符串
  let mergedList = [].concat(...list).filter((item) => item !== '')
  if (mergedList.length == 0) {
    text.text = '请先选择模型或输入模型id'
    return
  } else {
    // 发起请求
    mergedList.forEach(async (modelId: string) => {
      arg.model_id = modelId
      arg.key = 'wHzwvPzl70HdTBIvLdzJZMxHrpdSWyA1ARVXVU5w9YQzMw9oO6WhiIlkpOUY' // 请替换为您的实际 API Key

      try {
        const rs = await Pixihttp.get_image(arg)
        pollForImage(rs)

        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"
                        :title="'   模型ID: ' + 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.url"
                        alt="Gallery Image"
                        class="gallery-image"
                      />
                      <div>{{ image.modelId }}</div>
                    </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>
帮我增加一个按钮 清空selected的值