<template>
  <div id="desktop-app">
    <TheSidebar
      :groups="sidebarGroups"
      :base-overrides="sidebarOverrides"
      :hidden-base-ids="hiddenBaseIds"
      @add="openAddGroup"
      @edit-group="openEditGroup"
      @remove-group="handleRemoveGroup"
      @settings="toggleSettings"
    />
    <MainContent />
    <TheContextMenu
      @add-icon="openAddIcon"
      @edit-icon="openEditIcon"
      @edit-widget="openEditWidget"
      @settings="openSettings"
    />
    <SettingsPanel v-model:open="isSettingsOpen" />
    <EditIconDialog
      v-model:open="isEditIconOpen"
      :icon="editingIcon"
      @submit="handleEditIcon"
    />
    <AddGroupDialog
      v-model:open="isGroupDialogOpen"
      :title="dialogTitle"
      :submit-text="dialogSubmitText"
      :initial-name="dialogInitialName"
      :initial-icon-id="dialogInitialIconId"
      @submit="handleGroupSubmit"
    />
    <AddIconDialog
      v-model:open="isAddIconOpen"
      :mode="addIconMode"
      :initial-tab="addIconInitialTab"
      :target-widget-id="replaceWidgetId"
      @submit="handleAddIcon"
      @add-widget="handleAddWidget"
      @replace-widget="handleReplaceWidget"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import TheSidebar from './components/TheSidebar/index.vue';
import MainContent from './components/MainContent/index.vue';
import TheContextMenu from './components/TheContextMenu/index.vue';
import AddGroupDialog from './components/AddGroupDialog/index.vue';
import AddIconDialog from './components/AddIconDialog/index.vue';
import EditIconDialog from './components/EditIconDialog/index.vue';
import SettingsPanel from './components/SettingsPanel/index.vue';
import { sidebarBaseItems } from './config/sidebarItems';
import { useLayoutStore } from './store/useLayoutStore';
import { useWidgetsStore } from './store/useWidgetsStore';
import { useSettingsSync } from './composables/useSettingsSync';

type SidebarGroup = {
  id: string;
  label: string;
  iconId: string;
};

type SidebarOverride = {
  label: string;
  iconId: string;
};

const GROUPS_STORAGE_KEY = 'itab_sidebar_groups';
const OVERRIDES_STORAGE_KEY = 'itab_sidebar_overrides';
const HIDDEN_STORAGE_KEY = 'itab_sidebar_hidden';

const loadGroups = (): SidebarGroup[] => {
  const raw = localStorage.getItem(GROUPS_STORAGE_KEY);
  if (!raw) return [];
  try {
    const parsed = JSON.parse(raw);
    if (!Array.isArray(parsed)) return [];
    return parsed.filter(
      (item): item is SidebarGroup =>
        item &&
        typeof item.id === 'string' &&
        typeof item.label === 'string' &&
        typeof item.iconId === 'string'
    );
  } catch {
    return [];
  }
};

const sidebarGroups = ref<SidebarGroup[]>(loadGroups());
const sidebarOverrides = ref<Record<string, SidebarOverride>>({});
const hiddenBaseIds = ref<string[]>([]);
const isGroupDialogOpen = ref(false);
const isAddIconOpen = ref(false);
const isEditIconOpen = ref(false);
const isSettingsOpen = ref(false);
const addIconMode = ref<'add' | 'replace-widget'>('add');
const addIconInitialTab = ref<'widgets' | 'sites' | 'custom'>('widgets');
const replaceWidgetId = ref<string | null>(null);
const editTarget = ref<{ id: string; source: 'base' | 'group' } | null>(null);
const layoutStore = useLayoutStore();
const widgetsStore = useWidgetsStore();
const editingIcon = ref<{ id: string; name: string; url: string; img?: string; text?: string; bgColor?: string } | null>(null);

useSettingsSync();

const loadOverrides = (): Record<string, SidebarOverride> => {
  const raw = localStorage.getItem(OVERRIDES_STORAGE_KEY);
  if (!raw) return {};
  try {
    const parsed = JSON.parse(raw);
    if (!parsed || typeof parsed !== 'object') return {};
    return Object.fromEntries(
      Object.entries(parsed).filter(
        ([, value]) =>
          value &&
          typeof value === 'object' &&
          typeof (value as SidebarOverride).label === 'string' &&
          typeof (value as SidebarOverride).iconId === 'string'
      )
    );
  } catch {
    return {};
  }
};

const loadHidden = (): string[] => {
  const raw = localStorage.getItem(HIDDEN_STORAGE_KEY);
  if (!raw) return [];
  try {
    const parsed = JSON.parse(raw);
    if (!Array.isArray(parsed)) return [];
    return parsed.filter((value): value is string => typeof value === 'string');
  } catch {
    return [];
  }
};

sidebarOverrides.value = loadOverrides();
hiddenBaseIds.value = loadHidden();

const openAddGroup = () => {
  editTarget.value = null;
  isGroupDialogOpen.value = true;
};

const openSettings = () => {
  isSettingsOpen.value = true;
};

const toggleSettings = () => {
  isSettingsOpen.value = !isSettingsOpen.value;
};

const openAddIcon = () => {
  addIconMode.value = 'add';
  addIconInitialTab.value = 'widgets';
  replaceWidgetId.value = null;
  isAddIconOpen.value = true;
};

const openEditWidget = (widgetId: string) => {
  addIconMode.value = 'replace-widget';
  addIconInitialTab.value = 'widgets';
  replaceWidgetId.value = widgetId;
  isAddIconOpen.value = true;
};

const openEditIcon = (iconId: string) => {
  const icon = layoutStore.icons.find(item => item.id === iconId);
  if (!icon) return;
  editingIcon.value = { ...icon };
  isEditIconOpen.value = true;
};

const openEditGroup = (payload: { id: string; source: 'base' | 'group' }) => {
  editTarget.value = payload;
  isGroupDialogOpen.value = true;
};

const handleRemoveGroup = (payload: { id: string; source: 'base' | 'group' }) => {
  if (payload.source === 'group') {
    sidebarGroups.value = sidebarGroups.value.filter(group => group.id !== payload.id);
    localStorage.setItem(GROUPS_STORAGE_KEY, JSON.stringify(sidebarGroups.value));
    return;
  }
  if (!hiddenBaseIds.value.includes(payload.id)) {
    hiddenBaseIds.value = [...hiddenBaseIds.value, payload.id];
    localStorage.setItem(HIDDEN_STORAGE_KEY, JSON.stringify(hiddenBaseIds.value));
  }
};

const dialogTitle = computed(() => (editTarget.value ? '编辑分组' : '添加分组'));
const dialogSubmitText = computed(() => (editTarget.value ? '保存' : '添加'));

const dialogInitialData = computed(() => {
  if (!editTarget.value) return null;
  if (editTarget.value.source === 'group') {
    return sidebarGroups.value.find(group => group.id === editTarget.value?.id) ?? null;
  }
  const base = sidebarBaseItems.find(item => item.id === editTarget.value?.id);
  if (!base) return null;
  const override = sidebarOverrides.value[base.id];
  return {
    id: base.id,
    label: override?.label ?? base.label,
    iconId: override?.iconId ?? base.iconId ?? '',
  };
});

const dialogInitialName = computed(() => dialogInitialData.value?.label ?? '');
const dialogInitialIconId = computed(() => dialogInitialData.value?.iconId ?? '');

const handleGroupSubmit = (payload: { name: string; iconId: string }) => {
  const name = payload.name.trim();
  if (!name) return;
  if (editTarget.value) {
    if (editTarget.value.source === 'group') {
      sidebarGroups.value = sidebarGroups.value.map(group =>
        group.id === editTarget.value?.id
          ? { ...group, label: name, iconId: payload.iconId }
          : group
      );
      localStorage.setItem(GROUPS_STORAGE_KEY, JSON.stringify(sidebarGroups.value));
    } else {
      sidebarOverrides.value = {
        ...sidebarOverrides.value,
        [editTarget.value.id]: { label: name, iconId: payload.iconId },
      };
      localStorage.setItem(OVERRIDES_STORAGE_KEY, JSON.stringify(sidebarOverrides.value));
      hiddenBaseIds.value = hiddenBaseIds.value.filter(id => id !== editTarget.value?.id);
      localStorage.setItem(HIDDEN_STORAGE_KEY, JSON.stringify(hiddenBaseIds.value));
    }
  } else {
    const group: SidebarGroup = {
      id: `group-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
      label: name,
      iconId: payload.iconId,
    };
    sidebarGroups.value = [...sidebarGroups.value, group];
    localStorage.setItem(GROUPS_STORAGE_KEY, JSON.stringify(sidebarGroups.value));
  }
  isGroupDialogOpen.value = false;
};

const handleAddIcon = (payload: { name: string; url: string; bgColor: string; img?: string; text?: string }) => {
  layoutStore.addIcon({
    name: payload.name,
    url: payload.url,
    bgColor: payload.bgColor,
    img: payload.img,
    text: payload.text,
  });
};

const handleEditIcon = (payload: { id: string; name: string; url: string; bgColor: string; img?: string; text?: string }) => {
  layoutStore.updateIcon(payload.id, {
    name: payload.name,
    url: payload.url,
    bgColor: payload.bgColor,
    img: payload.img,
    text: payload.text,
  });
};

const handleAddWidget = (payload: { component: string; size?: '1x1' | '1x2' | '2x1' | '2x2' | '2x4'; data?: any }) => {
  widgetsStore.addWidget({
    component: payload.component,
    size: payload.size,
    data: payload.data,
  });
};

const handleReplaceWidget = (payload: { id: string; component: string; size?: '1x1' | '1x2' | '2x1' | '2x2' | '2x4'; data?: any }) => {
  widgetsStore.replaceWidget(payload.id, {
    component: payload.component,
    size: payload.size,
    data: payload.data,
  });
};

watch(isGroupDialogOpen, open => {
  if (!open) {
    editTarget.value = null;
  }
});

watch(isEditIconOpen, open => {
  if (!open) {
    editingIcon.value = null;
  }
});

watch(isAddIconOpen, open => {
  if (!open) {
    addIconMode.value = 'add';
    addIconInitialTab.value = 'widgets';
    replaceWidgetId.value = null;
  }
});
</script>

<style lang="scss">
#desktop-app {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  display: flex;
}
</style>
