<script setup lang="ts">
import { ref, computed, watch, useAttrs } from "vue";
import { useCustomizerStore } from "@/stores/customizer";
import { useModuleI18n } from "@/i18n/composables";
import UninstallConfirmDialog from "./UninstallConfirmDialog.vue";
import PluginPlatformChip from "./PluginPlatformChip.vue";
import StyledMenu from "./StyledMenu.vue";
import defaultPluginIcon from "@/assets/images/plugin_icon.png";
import { usePluginI18n } from "@/utils/pluginI18n";

const props = defineProps({
  extension: {
    type: Object,
    required: true,
  },
  marketMode: {
    type: Boolean,
    default: false,
  },
  highlight: {
    type: Boolean,
    default: false,
  },
  isPinned: {
    type: Boolean,
    default: false,
  },
});

// 定义要发送到父组件的事件
const emit = defineEmits([
  "configure",
  "update",
  "reload",
  "uninstall",
  "toggle-activation",
  "view-handlers",
  "view-readme",
  "view-changelog",
  "toggle-pin",
  "open-webui",
  "change-source",
]);

const attrs = useAttrs();

// 国际化
const { tm } = useModuleI18n("features/extension");
const { pluginName, pluginDesc } = usePluginI18n();

const hasPages = computed(() => {
  return (
    Array.isArray(props.extension?.pages) && props.extension.pages.length > 0
  );
});

const updateDisabledReason = computed(() => {
  return (
    props.extension?.update_disabled_reason || tm("messages.updateDisabled")
  );
});

const canUpdateExtension = computed(() => {
  return props.marketMode || props.extension?.updates_enabled !== false;
});

const showUninstallDialog = ref(false);

const supportPlatforms = computed(() => {
  const platforms = props.extension?.support_platforms;
  if (!Array.isArray(platforms)) {
    return [];
  }
  return platforms.filter((item) => typeof item === "string");
});

const astrbotVersionRequirement = computed(() => {
  const versionSpec = props.extension?.astrbot_version;
  return typeof versionSpec === "string" && versionSpec.trim().length
    ? versionSpec.trim()
    : "";
});

const logoLoadFailed = ref(false);

const logoSrc = computed(() => {
  const logo = props.extension?.logo;
  if (logoLoadFailed.value) {
    return defaultPluginIcon;
  }
  return typeof logo === "string" && logo.trim().length
    ? logo
    : defaultPluginIcon;
});

const localizedName = computed(() => pluginName(props.extension));

const localizedDesc = computed(() => pluginDesc(props.extension));

watch(
  () => props.extension?.logo,
  () => {
    logoLoadFailed.value = false;
  },
);

// 操作函数
const configure = () => {
  emit("configure", props.extension);
};

const updateExtension = () => {
  if (!canUpdateExtension.value) return;
  emit("update", props.extension);
};

const reloadExtension = () => {
  emit("reload", props.extension);
};

const changePluginSource = () => {
  emit("change-source", props.extension);
};

const uninstallExtension = async () => {
  showUninstallDialog.value = true;
};

const handleUninstallConfirm = (options: {
  deleteConfig: boolean;
  deleteData: boolean;
}) => {
  emit("uninstall", props.extension, options);
};

const toggleActivation = () => {
  emit("toggle-activation", props.extension);
};

const viewHandlers = () => {
  emit("view-handlers", props.extension);
};

const viewReadme = () => {
  emit("view-readme", props.extension);
};

const viewChangelog = () => {
  emit("view-changelog", props.extension);
};

const togglePin = () => {
  emit("toggle-pin", props.extension);
};

const openWebui = () => {
  emit("open-webui", props.extension);
};
</script>

<template>
  <v-card
    v-bind="attrs"
    class="extension-card mx-auto d-flex flex-column h-100"
    elevation="0"
    height="100%"
    :ripple="false"
    variant="outlined"
    :style="{
      position: 'relative',
      backgroundColor:
        useCustomizerStore().uiTheme === 'PurpleTheme'
          ? marketMode
            ? '#f8f0dd'
            : '#ffffff'
          : marketMode
          ? '#3a3425'
          : '#282833',
      color:
        useCustomizerStore().uiTheme === 'PurpleTheme'
          ? '#000000dd'
          : '#ffffffdd',
    }"
  >
    <v-card-text class="extension-card-text">
      <div class="extension-content-row">
        <div class="extension-image-container">
          <img
            :src="logoSrc"
            :alt="extension.name"
            class="extension-logo"
            @error="logoLoadFailed = true"
          />
        </div>

        <div class="extension-meta-group">
          <div class="extension-title-row">
            <p
              class="text-h3 font-weight-black extension-title"
              :class="{ 'text-h4': $vuetify.display.xs }"
            >
              <v-tooltip
                location="top"
                :text="
                  localizedName?.length && localizedName !== extension.name
                    ? `${localizedName} (${extension.name})`
                    : extension.name
                "
              >
                <template v-slot:activator="{ props: titleTooltipProps }">
                  <span
                    v-bind="titleTooltipProps"
                    class="extension-title__text"
                    >{{ localizedName }}</span
                  >
                </template>
              </v-tooltip>
              <span v-if="extension.version" class="extension-version">
                {{ extension.version }}
              </span>
              <v-chip
                v-if="extension.reserved"
                color="primary"
                size="x-small"
                class="extension-system-chip"
              >
                {{ tm("status.system") }}
              </v-chip>
              <v-tooltip
                location="top"
                v-if="extension?.has_update && !marketMode"
              >
                <template v-slot:activator="{ props: tooltipProps }">
                  <v-icon
                    v-bind="tooltipProps"
                    color="warning"
                    class="ml-2"
                    icon="mdi-update"
                    size="small"
                    style="cursor: pointer"
                    @click.stop="updateExtension"
                  ></v-icon>
                </template>
                <span
                  >{{ tm("card.status.hasUpdate") }}:
                  {{ extension.online_version }}</span
                >
              </v-tooltip>
            </p>

            <template v-if="!marketMode">
              <v-tooltip location="left">
                <template v-slot:activator="{ props: tooltipProps }">
                  <div class="extension-switch-wrap" @click.stop>
                    <div
                      v-bind="tooltipProps"
                      style="display: inline-flex; align-items: center"
                    >
                      <v-switch
                        :model-value="extension.activated"
                        color="success"
                        density="compact"
                        hide-details
                        inset
                        @update:model-value="toggleActivation"
                      ></v-switch>
                    </div>
                  </div>
                </template>
                <span>{{
                  extension.activated
                    ? tm("buttons.disable")
                    : tm("buttons.enable")
                }}</span>
              </v-tooltip>
            </template>
          </div>

          <div class="extension-chip-group d-flex flex-wrap">
            <v-chip
              v-if="extension?.has_update"
              color="warning"
              label
              size="small"
              style="cursor: pointer"
              @click.stop="updateExtension"
            >
              <v-icon icon="mdi-arrow-up-bold" start></v-icon>
              {{ extension.online_version }}
            </v-chip>
            <v-chip
              v-for="tag in extension.tags"
              :key="tag"
              :color="tag === 'danger' ? 'error' : 'primary'"
              label
              size="small"
            >
              {{ tag === "danger" ? tm("tags.danger") : tag }}
            </v-chip>
            <PluginPlatformChip :platforms="supportPlatforms" />
            <v-chip
              v-if="astrbotVersionRequirement"
              color="secondary"
              variant="outlined"
              label
              size="small"
            >
              AstrBot: {{ astrbotVersionRequirement }}
            </v-chip>
          </div>

          <div
            class="extension-desc"
            :class="{ 'text-caption': $vuetify.display.xs }"
          >
            {{ localizedDesc }}
          </div>
        </div>
      </div>
    </v-card-text>

    <v-card-actions class="extension-actions">
      <template v-if="!marketMode">
        <v-spacer></v-spacer>
        <v-tooltip location="top">
          <template v-slot:activator="{ props: pinTooltipProps }">
            <v-btn
              v-bind="pinTooltipProps"
              :aria-label="isPinned ? tm('buttons.unpin') : tm('buttons.pin')"
              :color="isPinned ? 'primary' : 'secondary'"
              :icon="isPinned ? 'mdi-pin' : 'mdi-pin-outline'"
              size="small"
              variant="tonal"
              class="extension-pin-btn"
              @click.stop="togglePin"
            ></v-btn>
          </template>
          <span>{{ isPinned ? tm("buttons.unpin") : tm("buttons.pin") }}</span>
        </v-tooltip>

        <v-tooltip location="top" :text="tm('buttons.viewDocs')">
          <template v-slot:activator="{ props: actionProps }">
            <v-btn
              v-bind="actionProps"
              icon="mdi-book-open-page-variant"
              size="small"
              variant="tonal"
              color="info"
              @click.stop="viewReadme"
            ></v-btn>
          </template>
        </v-tooltip>

        <v-tooltip
          v-if="hasPages"
          location="top"
          :text="tm('buttons.openWebui')"
        >
          <template v-slot:activator="{ props: actionProps }">
            <v-btn
              v-bind="actionProps"
              icon="mdi-monitor-dashboard"
              size="small"
              variant="tonal"
              color="primary"
              :disabled="!extension.activated"
              @click.stop="openWebui"
            ></v-btn>
          </template>
        </v-tooltip>

        <v-tooltip location="top" :text="tm('card.actions.pluginConfig')">
          <template v-slot:activator="{ props: actionProps }">
            <v-btn
              v-bind="actionProps"
              icon="mdi-cog"
              size="small"
              variant="tonal"
              color="primary"
              @click.stop="configure"
            ></v-btn>
          </template>
        </v-tooltip>

        <v-tooltip location="top" :text="tm('card.actions.reloadPlugin')">
          <template v-slot:activator="{ props: actionProps }">
            <v-btn
              v-bind="actionProps"
              icon="mdi-refresh"
              size="small"
              variant="tonal"
              color="primary"
              @click.stop="reloadExtension"
            ></v-btn>
          </template>
        </v-tooltip>

        <StyledMenu location="top end" offset="8">
          <template #activator="{ props: menuProps }">
            <v-btn
              v-bind="menuProps"
              icon="mdi-dots-horizontal"
              size="small"
              variant="tonal"
              color="secondary"
              @click.stop
            ></v-btn>
          </template>

          <v-list-item
            class="styled-menu-item"
            prepend-icon="mdi-information"
            @click.stop="viewHandlers"
          >
            <v-list-item-title>{{ tm("buttons.viewInfo") }}</v-list-item-title>
          </v-list-item>

          <v-tooltip
            location="left"
            :disabled="canUpdateExtension"
            :text="updateDisabledReason"
          >
            <template v-slot:activator="{ props: tooltipProps }">
              <div v-bind="tooltipProps">
                <v-list-item
                  class="styled-menu-item"
                  prepend-icon="mdi-update"
                  :disabled="!canUpdateExtension"
                  @click.stop="updateExtension"
                >
                  <v-list-item-title>{{
                    extension.has_update
                      ? tm("card.actions.updateTo") +
                        " " +
                        extension.online_version
                      : tm("card.actions.reinstall")
                  }}</v-list-item-title>
                </v-list-item>
              </div>
            </template>
          </v-tooltip>

          <v-list-item
            class="styled-menu-item"
            prepend-icon="mdi-source-branch"
            @click.stop="changePluginSource"
          >
            <v-list-item-title>{{
              tm("card.actions.changeSource")
            }}</v-list-item-title>
          </v-list-item>

          <v-list-item
            class="styled-menu-item"
            prepend-icon="mdi-delete"
            @click.stop="uninstallExtension"
          >
            <v-list-item-title class="text-error">{{
              tm("card.actions.uninstallPlugin")
            }}</v-list-item-title>
          </v-list-item>
        </StyledMenu>
      </template>
      <template v-else>
        <v-btn color="primary" size="small" @click.stop="viewReadme">
          {{ tm("buttons.viewDocs") }}
        </v-btn>
      </template>
    </v-card-actions>
  </v-card>

  <!-- 卸载确认对话框 -->
  <UninstallConfirmDialog
    v-model="showUninstallDialog"
    @confirm="handleUninstallConfirm"
  />
</template>

<style scoped>
.extension-card-text {
  padding: 12px 14px 8px;
  width: 100%;
}

.extension-card {
  cursor: pointer;
}

.extension-image-container {
  display: flex;
  align-items: flex-start;
  flex-shrink: 0;
}

.extension-logo {
  width: 64px;
  height: 64px;
  border-radius: 10px;
  object-fit: cover;
}

.extension-content-row {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.extension-meta-group {
  flex: 1;
  min-width: 0;
}

.extension-chip-group {
  gap: 6px;
}

.extension-desc {
  margin-top: 6px;
  font-size: 90%;
  display: -webkit-box;
  line-clamp: 2;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.extension-title {
  display: flex;
  align-items: center;
  min-width: 0;
  flex: 1;
  margin: 0;
}

.extension-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.extension-title__text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.extension-version {
  color: rgba(var(--v-theme-on-surface), 0.48);
  flex-shrink: 0;
  font-size: 0.875rem;
  font-weight: 500;
  margin-left: 10px;
  white-space: nowrap;
}

.extension-system-chip {
  flex-shrink: 0;
  margin-left: 8px;
}

.extension-switch-wrap {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.extension-pin-btn {
  flex-shrink: 0;
}

.extension-switch-wrap :deep(.v-switch) {
  margin: 0;
}

@media (max-width: 600px) {
  .extension-content-row {
    gap: 10px;
  }

  .extension-logo {
    width: 52px;
    height: 52px;
  }
}

.extension-actions {
  margin-top: auto;
  gap: 6px;
  justify-content: flex-end;
  min-height: 42px;
  padding: 0 12px 10px;
}
</style>
