import React, { useReducer, useEffect, useCallback } from 'react';
import {
  Modal,
  Badge,
  Button,
  Group,
  Title,
  Stack,
  Accordion,
} from '@mantine/core';
import { notifications } from '@mantine/notifications';
import { useWorkspace } from '../../../hooks/useWorkspace';
import AppearanceSettings from './AppearanceSettings';
import EditorSettings from './EditorSettings';
import GitSettings from './GitSettings';
import GeneralSettings from './GeneralSettings';
import { useModalContext } from '../../../contexts/ModalContext';
import DangerZoneSettings from './DangerZoneSettings';
import AccordionControl from '../AccordionControl';
import {
  type Theme,
  type Workspace,
  type SettingsAction,
  SettingsActionType,
} from '@/types/models';
import { getAccordionStyles } from '@/utils/themeStyles';
// State and reducer for workspace settings
interface WorkspaceSettingsState {
  localSettings: Partial<Workspace>;
  initialSettings: Partial<Workspace>;
  hasUnsavedChanges: boolean;
}

const initialState: WorkspaceSettingsState = {
  localSettings: {},
  initialSettings: {},
  hasUnsavedChanges: false,
};

function settingsReducer(
  state: WorkspaceSettingsState,
  action: SettingsAction<Partial<Workspace>>
): WorkspaceSettingsState {
  switch (action.type) {
    case SettingsActionType.INIT_SETTINGS:
      return {
        ...state,
        localSettings: action.payload || {},
        initialSettings: action.payload || {},
        hasUnsavedChanges: false,
      };
    case SettingsActionType.UPDATE_LOCAL_SETTINGS: {
      const newLocalSettings = { ...state.localSettings, ...action.payload };
      const hasChanges =
        JSON.stringify(newLocalSettings) !==
        JSON.stringify(state.initialSettings);
      return {
        ...state,
        localSettings: newLocalSettings,
        hasUnsavedChanges: hasChanges,
      };
    }
    case SettingsActionType.MARK_SAVED:
      return {
        ...state,
        initialSettings: state.localSettings,
        hasUnsavedChanges: false,
      };
    default:
      return state;
  }
}

const WorkspaceSettings: React.FC = () => {
  const { currentWorkspace, updateSettings, updateColorScheme, colorScheme } =
    useWorkspace();
  const { settingsModalVisible, setSettingsModalVisible } = useModalContext();
  const [state, dispatch] = useReducer(settingsReducer, initialState);

  useEffect(() => {
    if (currentWorkspace && settingsModalVisible) {
      const settings: Partial<Workspace> = {
        name: currentWorkspace.name,
        theme: currentWorkspace.theme,
        autoSave: currentWorkspace.autoSave,
        showHiddenFiles: currentWorkspace.showHiddenFiles,
        gitEnabled: currentWorkspace.gitEnabled,
        gitUrl: currentWorkspace.gitUrl,
        gitUser: currentWorkspace.gitUser,
        gitToken: currentWorkspace.gitToken,
        gitAutoCommit: currentWorkspace.gitAutoCommit,
        gitCommitMsgTemplate: currentWorkspace.gitCommitMsgTemplate,
        gitCommitName: currentWorkspace.gitCommitName,
        gitCommitEmail: currentWorkspace.gitCommitEmail,
      };
      dispatch({ type: SettingsActionType.INIT_SETTINGS, payload: settings });
    }
  }, [currentWorkspace, settingsModalVisible]);

  const handleInputChange = useCallback(
    <K extends keyof Workspace>(key: K, value: Workspace[K]): void => {
      dispatch({
        type: SettingsActionType.UPDATE_LOCAL_SETTINGS,
        payload: { [key]: value } as Partial<Workspace>,
      });
    },
    []
  );

  const handleSubmit = async (): Promise<void> => {
    try {
      if (!state.localSettings.name?.trim()) {
        notifications.show({
          message: 'Workspace name cannot be empty',
          color: 'red',
        });
        return;
      }

      // Save with current Mantine theme
      const settingsToSave = {
        ...state.localSettings,
        theme: colorScheme as Theme,
      };

      await updateSettings(settingsToSave);
      dispatch({ type: SettingsActionType.MARK_SAVED });
      notifications.show({
        message: 'Settings saved successfully',
        color: 'green',
      });
      setSettingsModalVisible(false);
    } catch (error) {
      console.error('Failed to save settings:', error);
      notifications.show({
        message:
          'Failed to save settings: ' +
          (error instanceof Error ? error.message : String(error)),
        color: 'red',
      });
    }
  };

  const handleClose = useCallback(() => {
    // Revert theme to saved state
    if (state.initialSettings.theme) {
      updateColorScheme(state.initialSettings.theme);
    }
    setSettingsModalVisible(false);
  }, [setSettingsModalVisible, state.initialSettings.theme, updateColorScheme]);

  return (
    <Modal
      opened={settingsModalVisible}
      onClose={handleClose}
      title={<Title order={2}>Workspace Settings</Title>}
      centered
      size="lg"
    >
      <Stack gap="xl">
        {state.hasUnsavedChanges && (
          <Badge color="yellow" variant="light">
            Unsaved Changes
          </Badge>
        )}

        <Accordion
          defaultValue={['general', 'appearance', 'editor', 'git', 'danger']}
          multiple
          styles={(theme) => ({
            ...getAccordionStyles(theme),
            chevron: {
              '&[data-rotate]': {
                transform: 'rotate(180deg)',
              },
            },
          })}
        >
          <Accordion.Item value="general">
            <AccordionControl>General</AccordionControl>
            <Accordion.Panel>
              <GeneralSettings
                name={state.localSettings.name || ''}
                onInputChange={handleInputChange}
              />
            </Accordion.Panel>
          </Accordion.Item>

          <Accordion.Item value="appearance">
            <AccordionControl>Appearance</AccordionControl>
            <Accordion.Panel>
              <AppearanceSettings />
            </Accordion.Panel>
          </Accordion.Item>

          <Accordion.Item value="editor">
            <AccordionControl>Editor</AccordionControl>
            <Accordion.Panel>
              <EditorSettings
                autoSave={state.localSettings.autoSave || false}
                onAutoSaveChange={(value: boolean) =>
                  handleInputChange('autoSave', value)
                }
                showHiddenFiles={state.localSettings.showHiddenFiles || false}
                onShowHiddenFilesChange={(value: boolean) =>
                  handleInputChange('showHiddenFiles', value)
                }
              />
            </Accordion.Panel>
          </Accordion.Item>

          <Accordion.Item value="git">
            <AccordionControl>Git Integration</AccordionControl>
            <Accordion.Panel>
              <GitSettings
                gitEnabled={state.localSettings.gitEnabled || false}
                gitUrl={state.localSettings.gitUrl || ''}
                gitUser={state.localSettings.gitUser || ''}
                gitToken={state.localSettings.gitToken || ''}
                gitAutoCommit={state.localSettings.gitAutoCommit || false}
                gitCommitMsgTemplate={
                  state.localSettings.gitCommitMsgTemplate || ''
                }
                gitCommitName={state.localSettings.gitCommitName || ''}
                gitCommitEmail={state.localSettings.gitCommitEmail || ''}
                onInputChange={handleInputChange}
              />
            </Accordion.Panel>
          </Accordion.Item>

          <Accordion.Item value="danger">
            <AccordionControl>Danger Zone</AccordionControl>
            <Accordion.Panel>
              <DangerZoneSettings />
            </Accordion.Panel>
          </Accordion.Item>
        </Accordion>

        <Group justify="flex-end">
          <Button variant="default" onClick={handleClose}>
            Cancel
          </Button>
          <Button onClick={() => void handleSubmit()}>Save Changes</Button>
        </Group>
      </Stack>
    </Modal>
  );
};

export default WorkspaceSettings;
