<template>
  <div 
    class="message-item mobile"
    :class="[ 'type-' + message.role ]"
    @longpress="onLongpress"
  >
    <!-- 多选模式 - 左 -->
    <div v-if="!message.isUser && isSelectMode" class="select-container">
      <CheckBox 
        :modelValue="isThisItemSelected" 
        @update:modelValue="setSelected($event as boolean)"
      />
    </div>

    <!-- 消息内容 -->
    <div class="message-content-container">

      <!-- 主消息内容 -->
      <div 
        class="message"
        :class="{ 'expanded': contentExpanded }"
      >
        <!-- 工具图标 -->
        <Icon v-if="message.role === 'tool'" class="prefix icon" name="ai-tools" />
        <!-- 加载和失败状态 -->
        <ActivityIndicator v-if="message.state === 'loading'" class="prefix icon" />
        <Icon icon="warning" v-else-if="message.state === 'error'" class="prefix icon" />

        <div class="content">

          <span v-if="message.statusText" :class="[ 'status-text', message.state ]">
            {{ message.statusText }}
          </span>

          <!-- 思考内容 -->
          <FlexRow v-if="message.reasoningContent" >
            <scroll-view
              scroll-y 
              :style="{
                maxHeight: reasoningContentExpanded ? '' : '200rpx'
              }" 
              :scroll-top="reasoningContentScrollTop">
              <FlexRow align="center" gap="gap.md" :padding="[10,0]">
                <Icon icon="ai-thinking" :size="26" />
                <text class="reasoning-content">
                  {{ reasoningContentExpanded ? message.reasoningContent : reasoningUnExpandContent }}
                </text>
              </FlexRow>
            </scroll-view>
            <IconButton 
              icon="arrow-down-bold"
              :rotate="reasoningContentExpanded ? 180 : 0"
              :size="26"
              @click="reasoningContentExpanded = !reasoningContentExpanded"
            />
          </FlexRow>

          <!-- 文本内容 -->
          <div v-if="message.type === 'text' && content" class="text-content">
            <zero-markdown-view v-if="contentHasMarkdown(content)" :markdown="content" :aiMode='true'></zero-markdown-view>
            <text v-else>{{ content }}</text>
          </div>
          <!-- 图片内容 -->
          <div v-if="message.type === 'image_url' && message.image_url" class="image-content">
            <image class="img" :src="message.image_url" />
          </div>
          <!-- 音频内容 -->
          <div v-if="message.type === 'input_audio' && message.input_audio?.data" class="audio-content">
            <audio :src="message.input_audio?.data" controls />
          </div>
          <!-- 视频内容 -->
          <div v-if="message.type === 'video' && message.content" class="video-content">
            <video :src="message.content" controls />
          </div>
          <!-- 视频内容 -->
          <div v-if="message.type === 'video_url' && message.video_url" class="video-content">
            <video :src="message.video_url" controls />
          </div>
        </div>
      </div>

      <!-- 额外内容 -->
      <div 
        v-if="message.extra" 
        :class="{
          'extra-container': true,
          'text-content': true,
          'expanded': extraExpanded
        }" 
      >
        <FlexCol v-if="extraExpanded" backgroundColor="background.tertiary" padding="15" radius="radius.sm">
          <text class="extra-content" >
            {{ message.extra }}
          </text>
        </FlexCol>
        <div class="button-container">
          <ExpandButton v-model:expanded="extraExpanded" />
        </div>
      </div>
        
      <!-- 额外快捷操作 -->
      <div v-if="message.actions" class="actions-container">
        <Button v-for="action in message.actions" :key="action" @click="emit('action', action)">
          {{ action }}
        </Button>
      </div>
    </div>

    <!-- 多选模式 - 右 -->
    <div v-if="message.isUser && isSelectMode" class="select-container">
      <CheckBox
        :modelValue="isThisItemSelected" 
        @update:modelValue="setSelected($event as boolean)"
      />
    </div>
  </div>
</template>

<script lang="ts" setup>
import type { ChatMessage } from '../model/Message';
import type { PropType } from 'vue';
import { computed, ref, toRef, watch } from 'vue';
import { useChatSelectionChild } from '../composables/useChatSelection';
import { TimeUtils } from '@imengyu/imengyu-utils';
import ExpandButton from './Compoents/ExpandButton.vue';
import CheckBox from '@/components/form/CheckBox.vue';
import ActivityIndicator from '@/components/basic/ActivityIndicator.vue';
import Icon from '@/components/basic/Icon.vue';
import Button from '@/components/basic/Button.vue';
import FlexRow from '@/components/layout/FlexRow.vue';
import FlexCol from '@/components/layout/FlexCol.vue';
import { actionSheet } from '@/components/dialog/CommonRoot';
import ZeroMarkdownView from '@/pages/chat/zero-markdown-view/components/zero-markdown-view/zero-markdown-view.vue';
import IconButton from '@/components/basic/IconButton.vue';

const props = defineProps({
  message: {
    type: Object as PropType<ChatMessage>,
    default: () => ({})
  },
  isGlobalLoading: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits([
  'delete', 'save', 'mulitSelect', 
  'action', 'confirmEdit', 'regenerate'
]);

//多选

const {
  isSelectMode,
  isThisItemSelected,
  setSelected,
} = useChatSelectionChild(toRef(props, 'message'));

//时间

const time = computed(() => {
  return TimeUtils.getBetterDate(props.message.timestamp)
})

//内容显示

const reasoningContentExpanded = ref(false);
const reasoningUnExpandContent = computed(() => {
  if (!props.message.reasoningContent)
    return '';
  switch (props.message.state) {
    case 'loading':
    case 'error':
      return props.message.reasoningContent;
    case 'success':
      return '深度思考完成' + (props.message.reasoningTime ? 
        `，已思考 ${(props.message.reasoningTime / 1000).toFixed(1)}s` : 
        ''
      );
  }
})
const reasoningContentScrollTop = computed(() => {
  return props.message.reasoningContent ? props.message.reasoningContent.length * 10 : 0;
})
const contentExpanded = ref(true);
const contentExpandable = computed(() => {
  return props.message.content && 
    props.message.content.length > 70 &&
    props.message.type === 'text'
})
const content = computed(() => {
  const content = props.message.content;
  return (contentExpanded.value && contentExpandable.value) || content.length < 70 ? 
    content : 
    (content.slice(0, 70) + '...')
})
const extraExpanded = ref(false);

function contentHasMarkdown(content: string): boolean {
  if (!content) 
    return false;
  // 标题
  if (/^ {0,3}#{1,6} /.test(content) || /(^|\n) {0,3}#{1,6} /.test(content)) return true;
  // 加粗/斜体（*或_成对包裹）
  if (/\*\*[^*]+?\*\*/.test(content) || /__[^_]+?__/.test(content)) return true;
  if (/\*[^*]+?\*/.test(content) || /_[^_]+?_/.test(content)) return true;
  // 行内代码块或代码块
  if (/`[^`]+?`/.test(content) || /```[\s\S]*?```/.test(content)) return true;
  // 链接/图片
  if (/\[([^\]]+)\]\(([^)]+)\)/.test(content) || /!\[([^\]]*)\]\(([^)]+)\)/.test(content)) return true;
  // 列表
  if (/^ {0,3}([-*+]|\d+\.) /m.test(content)) return true;
  // 引用
  if (/^ {0,3}> /m.test(content)) return true;
  // 分割线
  if (/^ {0,3}(-{3,}|\*{3,}|_{3,})$/m.test(content)) return true;
  // 表格
  if (/^\|(.+)\|/.test(content) && /\|/.test(content)) return true;
  return false;
}

//是否显示操作

const canShowActions = computed(() => {
  return !props.isGlobalLoading && (props.message.role === 'user'
    ? true
    : (!props.message.isEphemeral && props.message.state !== 'loading'))
})

const isUser = computed(() => {
  return props.message.role === 'user'
})
const isAI = computed(() => {
  return props.message.role === 'assistant'
})

watch(() => props.message, (m) => {
  //工具消息默认不展开内容
  if (m.role === 'tool') {
    contentExpanded.value = false;
  } else {
    contentExpanded.value = true;
  }
}, { immediate: true });

let oldChangedExpanded = '';

watch(isSelectMode, (v) => {
  if (v) {
    oldChangedExpanded = contentExpanded.value ? 'expanded' : '';
    contentExpanded.value = false;
  } else {
    if (oldChangedExpanded) {
      contentExpanded.value = oldChangedExpanded === 'expanded';
      oldChangedExpanded = '';
    }
  }
});

//保存
function copyMessage(message: ChatMessage) {
  uni.setClipboardData({
    data: message.content,
    success: () => {
      uni.showToast({
        title: '复制成功',
        icon: 'success',
      });
    },
  });
}

function onLongpress() {
  if (!canShowActions.value) 
    return;
  actionSheet({
    title: '消息操作',
    showCancel: true,
    actions: [
      {
        name: '复制',
      },
      {
        name: '删除',
        color: 'error',
      },
      {
        name: '多选',
      },
    ],
  }).then((result) => {
    switch (result) {
      case 0:
        copyMessage(props.message);
        break;
      case 1:
        emit('delete', props.message.id);
        break;
      case 2:
        emit('mulitSelect', [props.message.id]);
        break;
    }
  });
}
</script>

<style lang="scss">
.message-item {
  --color-background: #fff;
  --color-background-light: #f5f5f5;
  --color-ai: #ffffff;
  --color-user: #fafafa;
  --color-border: #e0e0e0;
  --color-border-light: #f0f0f0;
  --color-border-dark: #d0d0d0;
  --color-text: #333333;
  --color-text-light: #666666;
  --color-content-light: #d0d0d0;
  --color-content-dark: #333333;
  --color-surface: #ffffff;
  --color-surface-hover: #fafafa;
  --border-radius: 15rpx;
  --border-radius-small: 10rpx;

  position: relative;
  max-width: 100%;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 10rpx;
  margin-bottom: 20rpx;
  user-select: text;
  -webkit-user-select: text;

  .message-content-container  {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    flex: 1;
    max-width: 100%;
    min-width: 0;
  }
  .message {
    position: relative;
    padding: 12px 15px;
    border-radius: var(--border-radius);
    max-width: 95%;
    min-width: 0;
    word-wrap: break-word;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    overflow: hidden;

    &:hover {
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
    }
    &.expanded {
      align-items: flex-start;
    }

    >.icon {
      flex-shrink: 0;
    }

    .status-container {
      display: flex;
      align-items: center;
      gap: 2px;

      .status-text {
        font-size: 13px;
        color: var(--color-text-light);
    
        &.error {
          color: var(--color-danger);
        }
      }
    }

    //内容控制
    .content {
      display: flex;
      flex-direction: column;
      gap: 4px;
      font-size: 1rem;
      line-height: 1.5;
      color: var(--color-text);
      max-width: 100%;
      min-width: 0;

      //不同类型的内容样式
      .image-content {
        .img {
          max-width: 300px;
          height: auto;
          object-fit: cover;
          border-radius: var(--border-radius-small);
        }
      }
      .audio-content {
        audio {
          width: 400px;
          border-radius: var(--border-radius-small);
        }
      }
      .video-content {
        video {
          max-width: 100%;
          height: auto;
          border-radius: var(--border-radius-small);
        }
      }
      .file-content {
        display: flex;
        align-items: center;
        gap: 4px;
      }

      //思考内容 
      .reasoning-content {
        position: relative;
        font-size: 0.8rem;
        max-width: 500px;
        color: var(--color-text-light);
      }

      .prefix {
        display: inline-block;
        margin-right: 8px;
        vertical-align: middle;
      }
      
      //文本内容样式
      .text-content {
        display: flex;
        align-items: flex-start;
        flex-wrap: wrap;
      }
    }
    .time {
      font-size: 0.8rem;
      color: var(--color-text-light);
      margin-top: 6px;
      opacity: 0.8;
    }    
    .type-user .time {
      align-self: flex-end;
    }
    .type-ai .time {
      align-self: flex-start;
    }
  }
  .extra-container {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    max-width: 100%;

    &.expanded {
      overflow: hidden;

      .expand-icon {
        transform: rotate(180deg);
      }
      .button-container {
        position: relative;
      }
    }
    .expand-icon {
      transition: transform 0.3s ease;
    }
  }
  .actions-container {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    margin-top: 10px;
    gap: 2px;
  }
  .select-container {
    padding: 14px 0;
  }

  /* 不同消息类型的样式 */
  &.type-user {
    flex-direction: row-reverse;

    .message {
      background-color: var(--color-user);
      align-self: flex-end;
      border: 1px solid var(--color-border);
      border-top-right-radius: 0;
    }
  }
  &.type-system,
  &.type-tool,
  &.type-assistant {
    .message {  
      background-color: var(--color-ai);
      align-self: flex-start;
      border: 1px solid var(--color-border-light);
      border-top-left-radius: 0;
    }
  }
  &.type-tool {
    .message {
      border: none;
      padding: 5px 10px;
      box-shadow: none;
    }
  }

  &.mobile {
    .message {
      padding: 5px 10px;
    }

    &.message-item {
      margin-bottom: 46rpx;
    }

    &.type-user {
      .message-actions {
        justify-content: flex-end;
      }
    }
  }
}

</style>
