import { create } from "zustand";
import { v4 as uuidv4 } from "uuid";
import {
  PersonalityStore,
  PersonalityDataType,
  SectionItemType,
  TextType,
  ButtonType,
  ImageType,
  SocialType,
  HorizontalAlignment,
  VerticalAlignment,
  SelectedElement,
} from "../types/Types";

// Helper function to get sections sorted by sortNumber
export const getSortedSectionKeys = (data: PersonalityDataType): string[] => {
  return Object.keys(data).sort((a, b) => {
    const sortA = data[a].sortNumber || 0;
    const sortB = data[b].sortNumber || 0;
    return sortA - sortB;
  });
};

export const usePersonalityStore = create<PersonalityStore>((set, get) => ({
  data: {
    header: { name: "هدر", columnsCount: 1, items: [], sortNumber: 1 },
    content: {
      name: "محتوا",
      columnsCount: 1,
      items: [],
      isContent: true,
      sortNumber: 2,
    },
    footer: { name: "فوتر", columnsCount: 1, items: [], sortNumber: 3 },
  },

  activeSection: "",
  activeItemIndex: 0,
  selectedElement: null,
  isEditMode: false,

  setData: (data: PersonalityDataType) =>
    set(() => {
      // Normalize data to ensure all sections have names
      const normalizedData: PersonalityDataType = {};

      Object.entries(data).forEach(([key, section]) => {
        normalizedData[key] = {
          ...section,
          name:
            section.name ||
            (key === "header"
              ? "هدر"
              : key === "content"
              ? "محتوا"
              : key === "footer"
              ? "فوتر"
              : `سکشن ${key}`),
        };
      });

      return { data: normalizedData };
    }),

  setActiveSection: (section: string) =>
    set((state) => {
      const sectionData = state.data[section];

      if (!sectionData) {
        return state;
      }

      // اگر بخش آیتم ندارد و تعداد ستون‌ها بیشتر از صفر است، یک آیتم پیش‌فرض بساز
      if (sectionData.items.length === 0 && sectionData.columnsCount > 0) {
        const defaultItem = {
          id: uuidv4(),
          backgroundColor: "#ffffff",
          texts: [],
          buttons: [],
          images: [],
          socials: [],
          alignment: HorizontalAlignment.CENTER,
          verticalAlignment: VerticalAlignment.MIDDLE,
        };

        return {
          activeSection: section,
          activeItemIndex: 0,
          selectedElement: null,
          isEditMode: false,
          data: {
            ...state.data,
            [section]: {
              ...sectionData,
              items: [defaultItem],
            },
          },
        };
      }

      return {
        activeSection: section,
        activeItemIndex: 0,
        selectedElement: null,
        isEditMode: false,
      };
    }),

  setActiveItemIndex: (index: number) =>
    set(() => {
      return {
        activeItemIndex: index,
        selectedElement: null,
        isEditMode: false,
      };
    }),

  setSelectedElement: (element: SelectedElement) =>
    set({ selectedElement: element, isEditMode: !!element }),

  setEditMode: (isEdit: boolean) => set({ isEditMode: isEdit }),

  addSection: (afterSectionKey?: string) =>
    set((state) => {
      // Generate automatic section name
      const existingSectionNumbers = Object.values(state.data)
        .map((section) => {
          if (!section.name) return 0;
          const match = section.name.match(/سکشن (\d+)/);
          return match ? parseInt(match[1]) : 0;
        })
        .filter((num) => num > 0);

      const nextNumber =
        existingSectionNumbers.length > 0
          ? Math.max(...existingSectionNumbers) + 1
          : 1;

      const sectionName = `سکشن ${nextNumber}`;
      const sectionKey = `section_${nextNumber}`;

      if (state.data[sectionKey]) {
        return state; // Section already exists
      }

      // Calculate the sortNumber for the new section
      let newSortNumber = 1;
      if (afterSectionKey) {
        const afterSection = state.data[afterSectionKey];
        if (afterSection) {
          // Insert after the specified section, so sortNumber should be higher
          newSortNumber = afterSection.sortNumber + 1;

          // Update sortNumbers of sections that come after
          Object.keys(state.data).forEach((key) => {
            if (state.data[key].sortNumber > afterSection.sortNumber) {
              state.data[key].sortNumber += 1;
            }
          });
        }
      } else {
        // Add at the end - find the highest sortNumber and add 1
        const maxSortNumber = Math.max(
          ...Object.values(state.data).map((section) => section.sortNumber || 0)
        );
        newSortNumber = maxSortNumber + 1;
      }

      // Create new section data
      const newSection = {
        name: sectionName,
        columnsCount: 1,
        items: [],
        sortNumber: newSortNumber,
      };

      // If afterSectionKey is provided, insert after that section
      if (afterSectionKey) {
        const keys = Object.keys(state.data);
        const afterIndex = keys.indexOf(afterSectionKey);
        // TODO all index expect that increase +
        if (afterIndex !== -1) {
          const newData: typeof state.data = {};

          // Add sections before the target
          for (let i = 0; i <= afterIndex; i++) {
            newData[keys[i]] = state.data[keys[i]];
          }

          // Add new section
          newData[sectionKey] = newSection;

          // Add remaining sections
          for (let i = afterIndex + 1; i < keys.length; i++) {
            newData[keys[i]] = state.data[keys[i]];
          }

          return { data: newData };
        }
      }

      // Default: add at the end
      return {
        data: {
          ...state.data,
          [sectionKey]: newSection,
        },
      };
    }),

  removeSection: (sectionKey: string) =>
    set((state) => {
      // Cannot remove content section
      if (state.data[sectionKey]?.isContent) {
        return state;
      }

      const newData = { ...state.data };
      delete newData[sectionKey];

      return {
        data: newData,
        activeSection:
          state.activeSection === sectionKey ? "" : state.activeSection,
        selectedElement: null,
        isEditMode: false,
      };
    }),

  setColumnsCount: (sectionKey: string, columnsCount: number) =>
    set((state) => {
      const currentItems = state.data[sectionKey].items;
      const currentActiveItem = currentItems[state.activeItemIndex];

      const newItems = Array.from({ length: columnsCount }, (_, index) => {
        // اگر این آیتم در حال حاضر وجود دارد، آن را حفظ کن
        if (currentItems[index]) {
          return currentItems[index];
        }

        // اگر این اولین آیتم است و آیتم فعلی وجود دارد، از آن استفاده کن
        if (index === 0 && currentActiveItem) {
          return {
            ...currentActiveItem,
            id: currentActiveItem.id || uuidv4(),
          };
        }

        // در غیر این صورت، یک آیتم جدید بساز
        return {
          id: uuidv4(),
          backgroundColor: "#ffffff",
          texts: [],
          buttons: [],
          images: [],
          socials: [],
          alignment: HorizontalAlignment.CENTER,
          verticalAlignment: VerticalAlignment.MIDDLE,
        };
      });

      return {
        data: {
          ...state.data,
          [sectionKey]: {
            ...state.data[sectionKey],
            columnsCount,
            items: newItems,
          },
        },
        activeItemIndex: 0,
      };
    }),

  setSectionPadding: (sectionKey: string, padding: string) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          padding,
        },
      },
    })),

  setSectionHeight: (sectionKey: string, height: string) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          height,
        },
      },
    })),

  setSectionBorder: (
    sectionKey: string,
    border: {
      width?: string;
      color?: string;
      style?: "solid" | "dashed" | "dotted" | "none";
      sides?: ("top" | "bottom" | "left" | "right")[];
    }
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          border,
        },
      },
    })),

  setItems: (sectionKey: string, items: SectionItemType[]) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items,
        },
      },
    })),

  addItem: (sectionKey: string, item: Omit<SectionItemType, "id">) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: [...state.data[sectionKey].items, { ...item, id: uuidv4() }],
        },
      },
    })),

  updateActiveItem: (updates: Partial<SectionItemType>) =>
    set((state) => {
      if (!state.activeSection) return state;

      const sectionKey = state.activeSection;
      const items = state.data[sectionKey].items;
      const activeIndex = state.activeItemIndex;

      // اگر آیتم فعال وجود ندارد، یکی بساز
      if (activeIndex >= items.length) {
        const newItem = {
          id: uuidv4(),
          backgroundColor: "#ffffff",
          texts: [],
          buttons: [],
          images: [],
          socials: [],
          alignment: HorizontalAlignment.CENTER,
          verticalAlignment: VerticalAlignment.MIDDLE,
          ...updates,
        };

        const newItems = [...items];
        newItems[activeIndex] = newItem;

        return {
          data: {
            ...state.data,
            [sectionKey]: {
              ...state.data[sectionKey],
              items: newItems,
            },
          },
        };
      }

      const updatedItems = items.map((item, index) =>
        index === activeIndex ? { ...item, ...updates } : item
      );

      return {
        data: {
          ...state.data,
          [sectionKey]: {
            ...state.data[sectionKey],
            items: updatedItems,
          },
        },
      };
    }),

  updateItem: (
    sectionKey: string,
    id: string,
    updates: Partial<SectionItemType>
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === id ? { ...item, ...updates } : item
          ),
        },
      },
    })),

  removeItem: (sectionKey: string, id: string) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.filter((item) => item.id !== id),
        },
      },
    })),

  addText: (sectionKey: string, itemId: string, text: Omit<TextType, "id">) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  texts: [...(item.texts || []), { ...text, id: uuidv4() }],
                }
              : item
          ),
        },
      },
    })),

  addTextToActiveItem: (text: Omit<TextType, "id">) =>
    set((state) => {
      if (!state.activeSection) return state;

      const sectionKey = state.activeSection as string;
      const items = state.data[sectionKey].items;
      const activeIndex = state.activeItemIndex;

      if (activeIndex >= items.length) return state;

      const updatedItems = items.map((item, index) =>
        index === activeIndex
          ? {
              ...item,
              texts: [...(item.texts || []), { ...text, id: uuidv4() }],
            }
          : item
      );

      return {
        data: {
          ...state.data,
          [sectionKey]: {
            ...state.data[sectionKey],
            items: updatedItems,
          },
        },
      };
    }),

  addButton: (
    sectionKey: string,
    itemId: string,
    button: Omit<ButtonType, "id">
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  buttons: [
                    ...(item.buttons || []),
                    { ...button, id: uuidv4() },
                  ],
                }
              : item
          ),
        },
      },
    })),

  addButtonToActiveItem: (button: Omit<ButtonType, "id">) =>
    set((state) => {
      if (!state.activeSection) return state;

      const sectionKey = state.activeSection as string;
      const items = state.data[sectionKey].items;
      const activeIndex = state.activeItemIndex;

      if (activeIndex >= items.length) return state;

      const updatedItems = items.map((item, index) =>
        index === activeIndex
          ? {
              ...item,
              buttons: [...(item.buttons || []), { ...button, id: uuidv4() }],
            }
          : item
      );

      return {
        data: {
          ...state.data,
          [sectionKey]: {
            ...state.data[sectionKey],
            items: updatedItems,
          },
        },
      };
    }),

  updateText: (
    sectionKey: string,
    itemId: string,
    textId: string,
    updates: Partial<TextType>
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  texts: (item.texts || []).map((text) =>
                    text.id === textId ? { ...text, ...updates } : text
                  ),
                }
              : item
          ),
        },
      },
    })),

  updateButton: (
    sectionKey: string,
    itemId: string,
    buttonId: string,
    updates: Partial<ButtonType>
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  buttons: (item.buttons || []).map((button) =>
                    button.id === buttonId ? { ...button, ...updates } : button
                  ),
                }
              : item
          ),
        },
      },
    })),

  addImage: (
    sectionKey: string,
    itemId: string,
    image: Omit<ImageType, "id">
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  images: [...(item.images || []), { ...image, id: uuidv4() }],
                }
              : item
          ),
        },
      },
    })),

  addImageToActiveItem: (image: Omit<ImageType, "id">) =>
    set((state) => {
      if (!state.activeSection) return state;

      const sectionKey = state.activeSection as string;
      const items = state.data[sectionKey].items;
      const activeIndex = state.activeItemIndex;

      if (activeIndex >= items.length) return state;

      const updatedItems = items.map((item, index) =>
        index === activeIndex
          ? {
              ...item,
              images: [...(item.images || []), { ...image, id: uuidv4() }],
            }
          : item
      );

      return {
        data: {
          ...state.data,
          [sectionKey]: {
            ...state.data[sectionKey],
            items: updatedItems,
          },
        },
      };
    }),

  updateImage: (
    sectionKey: string,
    itemId: string,
    imageId: string,
    updates: Partial<ImageType>
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  images: (item.images || []).map((image) =>
                    image.id === imageId ? { ...image, ...updates } : image
                  ),
                }
              : item
          ),
        },
      },
    })),

  deleteText: (sectionKey: string, itemId: string, textId: string) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  texts: (item.texts || []).filter(
                    (text) => text.id !== textId
                  ),
                }
              : item
          ),
        },
      },
      selectedElement: null,
      isEditMode: false,
    })),

  deleteButton: (sectionKey: string, itemId: string, buttonId: string) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  buttons: (item.buttons || []).filter(
                    (button) => button.id !== buttonId
                  ),
                }
              : item
          ),
        },
      },
      selectedElement: null,
      isEditMode: false,
    })),

  deleteImage: (sectionKey: string, itemId: string, imageId: string) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  images: (item.images || []).filter(
                    (image) => image.id !== imageId
                  ),
                }
              : item
          ),
        },
      },
      selectedElement: null,
      isEditMode: false,
    })),

  addSocial: (
    sectionKey: string,
    itemId: string,
    social: Omit<SocialType, "id">
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  socials: [
                    ...(item.socials || []),
                    { ...social, id: uuidv4() },
                  ],
                }
              : item
          ),
        },
      },
    })),

  addSocialToActiveItem: (social: Omit<SocialType, "id">) =>
    set((state) => {
      if (!state.activeSection) return state;

      const sectionKey = state.activeSection as string;
      const items = state.data[sectionKey].items;
      const activeIndex = state.activeItemIndex;

      if (activeIndex >= items.length) return state;

      const updatedItems = items.map((item, index) =>
        index === activeIndex
          ? {
              ...item,
              socials: [...(item.socials || []), { ...social, id: uuidv4() }],
            }
          : item
      );

      return {
        data: {
          ...state.data,
          [sectionKey]: {
            ...state.data[sectionKey],
            items: updatedItems,
          },
        },
      };
    }),

  updateSocial: (
    sectionKey: string,
    itemId: string,
    socialId: string,
    updates: Partial<SocialType>
  ) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  socials: (item.socials || []).map((social) =>
                    social.id === socialId ? { ...social, ...updates } : social
                  ),
                }
              : item
          ),
        },
      },
    })),

  deleteSocial: (sectionKey: string, itemId: string, socialId: string) =>
    set((state) => ({
      data: {
        ...state.data,
        [sectionKey]: {
          ...state.data[sectionKey],
          items: state.data[sectionKey].items.map((item) =>
            item.id === itemId
              ? {
                  ...item,
                  socials: (item.socials || []).filter(
                    (social) => social.id !== socialId
                  ),
                }
              : item
          ),
        },
      },
      selectedElement: null,
      isEditMode: false,
    })),

  getSortedSectionKeys: () => getSortedSectionKeys(get().data),
}));
