import { Text } from '@/aesthetics/Text';
import { font, radius, spacing, useColors } from '@/aesthetics/styles';
import { useStrings } from '@/common/hooks/useStrings';
import { Pressable, StyleSheet, View } from 'react-native';
import { Card } from '@/see-log/aesthetics/Card';
import { IconPicker, preloadIconData } from '@/aesthetics/IconPicker';
import { useAlert } from '@/aesthetics/Alert';
import { useHaptics } from '@/aesthetics/useHaptics';
import { useEffect, useState, useCallback, useMemo } from 'react';
import { ArrowDown, ArrowUp } from 'lucide-react-native';
import { SelectLogger } from './SelectLogger';
import { CheckLogger } from './CheckLogger';
import { NumberMemoLogger } from './NumberMemoLogger';
import { TextMemoLogger } from './TextMemoLogger';
import { BasicMemoLogger } from './BasicMemoLogger';
import { MemoLoggerEditor } from './MemoLoggerEditor';
import { MemoLogCard } from './MemoLogCard';
import { LoggerTileGrid } from './LoggerTileGrid';
import { useMemoLog } from './useMemoLog';

type Sheet = 'basic' | 'create-logger' | 'edit-logger' | string | null;

export function AddLogCard() {
  const strings = useStrings();
  const c = useColors();
  const { showConfirm } = useAlert();
  const { notification, NotificationType } = useHaptics();

  const {
    entries,
    loggers,
    loggerMap,
    isLoading,
    createBasicLog,
    logWithLogger,
    logWithLoggerOption,
    logMultiselect,
    deleteEntry,
    createLogger,
    updateLogger,
    deleteLogger,
  } = useMemoLog();

  const [activeSheet, setActiveSheet] = useState<Sheet>(null);
  const [isEditMode, setIsEditMode] = useState(false);
  const [editingLoggerId, setEditingLoggerId] = useState<string | null>(null);
  const [iconPicker, setIconPicker] = useState<{
    index: number;
    onSelect: (icon: string) => void;
  } | null>(null);
  const [sortOrder, setSortOrder] = useState<'new_to_old' | 'old_to_new'>('new_to_old');

  useEffect(() => {
    preloadIconData();
  }, []);

  const sortedEntries = useMemo(
    () => (sortOrder === 'new_to_old' ? entries : [...entries].reverse()),
    [entries, sortOrder]
  );

  const activeLogger =
    activeSheet &&
    activeSheet !== 'basic' &&
    activeSheet !== 'create-logger' &&
    activeSheet !== 'edit-logger'
      ? loggerMap.get(activeSheet)
      : undefined;

  const editingLogger = editingLoggerId ? loggerMap.get(editingLoggerId) : undefined;

  const enterEditMode = () => {
    notification(NotificationType.Warning);
    setIsEditMode(true);
  };

  const closeSheet = () => {
    setActiveSheet(null);
    setEditingLoggerId(null);
  };

  const handleEditLogger = (id: string) => {
    setEditingLoggerId(id);
    setActiveSheet('edit-logger');
  };

  const handleBasicLog = useCallback(
    async (
      title: string,
      value: number | string,
      type: 'text' | 'number' | 'check',
      unit?: string
    ) => {
      await createBasicLog(title, value, type, unit);
      closeSheet();
    },
    [createBasicLog]
  );

  const handleCreateLogger = useCallback(
    async (logger: Parameters<typeof createLogger>[0]) => {
      await createLogger(logger);
      closeSheet();
    },
    [createLogger]
  );

  const handleUpdateLogger = useCallback(
    async (id: string, updates: Parameters<typeof updateLogger>[1]) => {
      await updateLogger(id, updates);
      closeSheet();
    },
    [updateLogger]
  );

  const handleOpenIconPicker = useCallback((index: number, onSelect: (icon: string) => void) => {
    setIconPicker({ index, onSelect });
  }, []);

  const handleSelectIcon = useCallback(
    (icon: string) => {
      iconPicker?.onSelect(icon);
      setIconPicker(null);
    },
    [iconPicker]
  );

  const getLoggerLabel = (l: { id: string; name: string }) =>
    strings.userCustomLogs[l.id] || l.name;

  return (
    <>
      <Card>
        <Text style={[styles.sectionTitle, { color: c.secondaryText }]}>
          {strings.userCustomLogs.loggers}
        </Text>
        <LoggerTileGrid
          memoLoggers={loggers}
          isLoading={isLoading}
          isEditMode={isEditMode}
          onEnterEditMode={enterEditMode}
          onExitEditMode={() => setIsEditMode(false)}
          onSelect={setActiveSheet}
          onEdit={handleEditLogger}
          onDelete={id => {
            const logger = loggerMap.get(id);
            const name = logger ? getLoggerLabel(logger) : '';
            showConfirm(
              strings.userCustomLogs.deleteLogger,
              strings.userCustomLogs.deleteConfirm(name),
              () => deleteLogger(id)
            );
          }}
          onAddNew={() => setActiveSheet('basic')}
          getLabel={getLoggerLabel}
        />

        {sortedEntries.length > 0 && (
          <>
            <View style={styles.logsHeader}>
              <Text style={[styles.sectionTitle, styles.logsTitle, { color: c.secondaryText }]}>
                {strings.userCustomLogs.logs}
              </Text>
              <Pressable
                onPress={() =>
                  setSortOrder(s => (s === 'new_to_old' ? 'old_to_new' : 'new_to_old'))
                }
                style={({ pressed }) => [
                  styles.sortButton,
                  { backgroundColor: c.tagBg },
                  pressed && { opacity: 0.7 },
                ]}
              >
                {sortOrder === 'new_to_old' ? (
                  <ArrowDown size={14} color={c.secondaryText} />
                ) : (
                  <ArrowUp size={14} color={c.secondaryText} />
                )}
                <Text style={[styles.sortLabel, { color: c.secondaryText }]}>
                  {sortOrder === 'new_to_old'
                    ? strings.userCustomLogs.newToOld
                    : strings.userCustomLogs.oldToNew}
                </Text>
              </Pressable>
            </View>
            <View style={styles.entryList}>
              {sortedEntries.map((entry, i) => (
                <MemoLogCard
                  key={entry.id}
                  entry={entry}
                  index={i}
                  onPress={() => {}}
                  onRequestDelete={() =>
                    showConfirm(
                      strings.userCustomLogs.deleteEntry,
                      strings.userCustomLogs.deleteConfirm(entry.title),
                      () => deleteEntry(entry.id)
                    )
                  }
                />
              ))}
            </View>
          </>
        )}
      </Card>

      <BasicMemoLogger
        visible={activeSheet === 'basic'}
        onClose={closeSheet}
        onLog={handleBasicLog}
        onCreateLogger={() => setActiveSheet('create-logger')}
      />

      <MemoLoggerEditor
        visible={activeSheet === 'create-logger' || activeSheet === 'edit-logger'}
        onClose={closeSheet}
        onCreate={handleCreateLogger}
        onUpdate={handleUpdateLogger}
        onOpenIconPicker={handleOpenIconPicker}
        logger={editingLogger}
      />

      {activeLogger?.type === 'singleselect' && activeLogger.options && (
        <SelectLogger
          visible
          title={getLoggerLabel(activeLogger)}
          options={activeLogger.options}
          colorBg={c.loggerBg}
          colorIcon={c.logger}
          onSelect={async ([i]) => {
            await logWithLoggerOption(activeLogger, i, getLoggerLabel(activeLogger));
            closeSheet();
          }}
          onClose={closeSheet}
        />
      )}

      {activeLogger?.type === 'multiselect' && activeLogger.options && (
        <SelectLogger
          visible
          title={getLoggerLabel(activeLogger)}
          options={activeLogger.options}
          colorBg={c.loggerBg}
          colorIcon={c.logger}
          selectLimit={activeLogger.options.length}
          onSelect={async indices => {
            await logMultiselect(activeLogger, indices, getLoggerLabel(activeLogger));
            closeSheet();
          }}
          onClose={closeSheet}
        />
      )}

      {activeLogger?.type === 'check' && (
        <CheckLogger
          visible
          title={getLoggerLabel(activeLogger)}
          onConfirm={async val => {
            await logWithLogger(activeLogger, val, undefined, getLoggerLabel(activeLogger));
            closeSheet();
          }}
          onClose={closeSheet}
        />
      )}

      {activeLogger?.type === 'number' && (
        <NumberMemoLogger
          visible
          title={getLoggerLabel(activeLogger)}
          unit={activeLogger.unit}
          onConfirm={async val => {
            await logWithLogger(activeLogger, val, undefined, getLoggerLabel(activeLogger));
            closeSheet();
          }}
          onClose={closeSheet}
        />
      )}

      {activeLogger?.type === 'text' && (
        <TextMemoLogger
          visible
          title={getLoggerLabel(activeLogger)}
          onConfirm={async val => {
            await logWithLogger(activeLogger, val, undefined, getLoggerLabel(activeLogger));
            closeSheet();
          }}
          onClose={closeSheet}
        />
      )}

      <IconPicker
        visible={iconPicker !== null}
        onClose={() => setIconPicker(null)}
        onSelect={handleSelectIcon}
      />
    </>
  );
}

const styles = StyleSheet.create({
  sectionTitle: { fontSize: font.md, fontWeight: '600', marginBottom: spacing.sm },
  logsTitle: { marginBottom: 0 },
  logsHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginTop: spacing.xl,
    marginBottom: spacing.sm,
  },
  sortButton: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: spacing.xs,
    paddingHorizontal: spacing.sm,
    paddingVertical: spacing.sm,
    borderRadius: radius.md,
  },
  sortLabel: { fontSize: font.xs, fontWeight: '500' },
  entryList: { gap: spacing.sm },
});
