import { defineStore } from "pinia";
import { ref, computed } from "vue";
import type {
  Conversation,
  Message,
  MessageContent,
  ConversationSettings,
} from "@/types/chat";
import { MessageRole } from "@/types/chat";
import { generateId, extractTitleFromMessage } from "@/utils/helpers";

export const useChatStore = defineStore("chat", () => {
  // 状态
  const conversations = ref<Conversation[]>([]);
  const currentConversationId = ref<string | null>(null);
  const isStreaming = ref(false);
  const streamController = ref<AbortController | null>(null);

  // 计算属性
  const currentConversation = computed(() => {
    return (
      conversations.value.find((c) => c.id === currentConversationId.value) ||
      null
    );
  });

  const sortedConversations = computed(() => {
    return [...conversations.value].sort((a, b) => {
      if (a.pinned && !b.pinned) return -1;
      if (!a.pinned && b.pinned) return 1;
      return b.updatedAt - a.updatedAt;
    });
  });

  const pinnedConversations = computed(() => {
    return sortedConversations.value.filter((c) => c.pinned && !c.archived);
  });

  const recentConversations = computed(() => {
    return sortedConversations.value.filter((c) => !c.pinned && !c.archived);
  });

  // 方法
  function createConversation(): string {
    const newConversation: Conversation = {
      id: generateId(),
      title: "新对话",
      messages: [],
      createdAt: Date.now(),
      updatedAt: Date.now(),
      pinned: false,
      archived: false,
      settings: undefined,
    };

    conversations.value.unshift(newConversation);
    currentConversationId.value = newConversation.id;
    saveToStorage();

    return newConversation.id;
  }

  function deleteConversation(id: string) {
    const index = conversations.value.findIndex((c) => c.id === id);
    if (index !== -1) {
      conversations.value.splice(index, 1);

      if (currentConversationId.value === id) {
        currentConversationId.value = conversations.value[0]?.id || null;
      }

      saveToStorage();
    }
  }

  function selectConversation(id: string) {
    currentConversationId.value = id;
  }

  function togglePinConversation(id: string) {
    const conversation = conversations.value.find((c) => c.id === id);
    if (conversation) {
      conversation.pinned = !conversation.pinned;
      saveToStorage();
    }
  }

  function renameConversation(id: string, newTitle: string) {
    const conversation = conversations.value.find((c) => c.id === id);
    if (conversation) {
      conversation.title = newTitle;
      conversation.updatedAt = Date.now();
      saveToStorage();
    }
  }

  function updateConversationSettings(
    id: string,
    convSettings: ConversationSettings,
  ) {
    const conversation = conversations.value.find((c) => c.id === id);
    if (conversation) {
      conversation.settings = { ...conversation.settings, ...convSettings };
      conversation.updatedAt = Date.now();
      saveToStorage();
    }
  }

  function addMessage(
    role: MessageRole,
    content: MessageContent,
    conversationId?: string,
  ): Message {
    const targetId = conversationId || currentConversationId.value;

    if (!targetId) {
      createConversation();
    }

    const conversation = conversations.value.find(
      (c) => c.id === (targetId || currentConversationId.value),
    );

    if (!conversation) {
      throw new Error("Conversation not found");
    }

    const message: any = {
      id: generateId(),
      role,
      content,
      timestamp: Date.now(),
      isStreaming: false,
    };

    conversation.messages.push(message);
    conversation.updatedAt = Date.now();

    if (
      role === MessageRole.USER &&
      conversation.messages.length === 1 &&
      content.text
    ) {
      conversation.title = extractTitleFromMessage(content.text);
    }

    saveToStorage();
    return message;
  }

  function updateMessage(messageId: string, updates: Partial<Message>) {
    const conversation = currentConversation.value;
    if (!conversation) return;

    const message = conversation.messages.find((m) => m.id === messageId);
    if (message) {
      Object.assign(message, updates);
      saveToStorage();
    }
  }

  function updateMessageContent(messageId: string, text: string) {
    const conversation = currentConversation.value;
    if (!conversation) return;

    const message = conversation.messages.find((m) => m.id === messageId);
    if (message) {
      message.content.text = text;
    }
  }

  function setMessageFeedback(
    messageId: string,
    feedback: "like" | "dislike" | null,
  ) {
    const conversation = currentConversation.value;
    if (!conversation) return;

    const message = conversation.messages.find((m) => m.id === messageId);
    if (message) {
      message.feedback = {
        liked: feedback === "like",
        disliked: feedback === "dislike",
        copied: message.feedback?.copied,
      };
      saveToStorage();
    }
  }

  function setMessageCopied(messageId: string) {
    const conversation = currentConversation.value;
    if (!conversation) return;

    const message = conversation.messages.find((m) => m.id === messageId);
    if (message) {
      message.feedback = {
        ...message.feedback,
        copied: true,
      };
    }
  }

  function startStreaming() {
    isStreaming.value = true;
    streamController.value = new AbortController();
  }

  function stopStreaming() {
    isStreaming.value = false;
    if (streamController.value) {
      streamController.value.abort();
      streamController.value = null;
    }
  }

  function clearConversation(id: string) {
    const conversation = conversations.value.find((c) => c.id === id);
    if (conversation) {
      conversation.messages = [];
      conversation.updatedAt = Date.now();
      saveToStorage();
    }
  }

  function saveToStorage() {
    try {
      localStorage.setItem(
        "chat-conversations",
        JSON.stringify(conversations.value),
      );
      localStorage.setItem(
        "chat-current-id",
        currentConversationId.value || "",
      );
    } catch (e) {
      console.error("Failed to save to storage:", e);
    }
  }

  function loadFromStorage() {
    try {
      const stored = localStorage.getItem("chat-conversations");
      if (stored) {
        conversations.value = JSON.parse(stored);
      }

      const storedId = localStorage.getItem("chat-current-id");
      if (storedId && conversations.value.find((c) => c.id === storedId)) {
        currentConversationId.value = storedId;
      } else if (conversations.value.length > 0) {
        currentConversationId.value = conversations.value[0].id;
      }
    } catch (e) {
      console.error("Failed to load from storage:", e);
    }
  }

  loadFromStorage();

  return {
    conversations,
    currentConversationId,
    isStreaming,
    streamController,
    currentConversation,
    sortedConversations,
    pinnedConversations,
    recentConversations,
    createConversation,
    deleteConversation,
    selectConversation,
    togglePinConversation,
    renameConversation,
    updateConversationSettings,
    addMessage,
    updateMessage,
    updateMessageContent,
    setMessageFeedback,
    setMessageCopied,
    startStreaming,
    stopStreaming,
    clearConversation,
    loadFromStorage,
  };
});
