import {
    ALPHABET_BY_LETTER,
    LETTERS_UPPER,
} from '../data/alphabet';

export type LetterTracingMode =
    | 'single-letter'
    | 'full-alphabet'
    | 'upper-lower-split'
    | 'two-column';

export type LetterCaseMode = 'upper' | 'lower' | 'both';

export interface LetterTracingGeneratorConfig {
    mode: LetterTracingMode;
    letterCase: LetterCaseMode;
    selectedLetter?: string;
    repetitions: number;
    fadePattern: 'gradient' | 'first-only';
}

export interface TracingCell {
    char: string;
    opacity: number;
    isGuide: boolean;
}

export interface TracingRow {
    displayChar: string;
    cells: TracingCell[];
}

export interface TeachingBlock {
    upper: string;
    lower: string;
    word: string;
    sentence: string;
    emoji: string;
}

export type LetterTracingData =
    | {
          mode: 'single-letter';
          teaching: TeachingBlock;
          rows: TracingRow[];
      }
    | {
          mode: 'full-alphabet';
          rows: TracingRow[];
      }
    | {
          mode: 'upper-lower-split';
          upperGlyphs: string[];
          lowerGlyphs: string[];
      }
    | {
          mode: 'two-column';
          leftRows: TracingRow[];
          rightRows: TracingRow[];
      };

function normalizeLetter(c: string): string {
    const u = c.trim().toUpperCase();
    return u.length ? u[0] : 'A';
}

function buildCells(
    char: string,
    count: number,
    fadePattern: 'gradient' | 'first-only',
): TracingCell[] {
    const n = Math.max(1, Math.min(12, count));
    const cells: TracingCell[] = [];
    for (let i = 0; i < n; i++) {
        let opacity: number;
        if (fadePattern === 'first-only') {
            opacity = i === 0 ? 1 : 0;
        } else if (n <= 1) {
            opacity = 1;
        } else {
            opacity = Math.max(0.12, 1 - i / (n - 1));
        }
        cells.push({ char, opacity, isGuide: i === 0 });
    }
    return cells;
}

function rowForChar(
    ch: string,
    repetitions: number,
    fadePattern: 'gradient' | 'first-only',
): TracingRow {
    return {
        displayChar: ch,
        cells: buildCells(ch, repetitions, fadePattern),
    };
}

export function generateLetterTracing(
    config: LetterTracingGeneratorConfig,
): LetterTracingData {
    const { mode, letterCase, repetitions, fadePattern } = config;

    if (mode === 'single-letter') {
        const key = normalizeLetter(config.selectedLetter ?? 'A');
        const meta = ALPHABET_BY_LETTER[key] ?? ALPHABET_BY_LETTER.A;
        const upper = key;
        const lower = key.toLowerCase();
        const teaching: TeachingBlock = {
            upper,
            lower,
            word: meta.word,
            sentence: `${upper} is for ${meta.word}`,
            emoji: meta.emoji,
        };
        const rows: TracingRow[] = [
            rowForChar(upper, repetitions, fadePattern),
            rowForChar(lower, repetitions, fadePattern),
        ];
        return { mode: 'single-letter', teaching, rows };
    }

    if (mode === 'full-alphabet') {
        const rows = LETTERS_UPPER.map((L) => {
            const ch = letterCase === 'lower' ? L.toLowerCase() : L;
            return rowForChar(ch, repetitions, fadePattern);
        });
        return { mode: 'full-alphabet', rows };
    }

    if (mode === 'upper-lower-split') {
        return {
            mode: 'upper-lower-split',
            upperGlyphs: [...LETTERS_UPPER],
            lowerGlyphs: LETTERS_UPPER.map((L) => L.toLowerCase()),
        };
    }

    // two-column
    const left = LETTERS_UPPER.slice(0, 13);
    const right = LETTERS_UPPER.slice(13);
    const mapChar = (L: string) =>
        letterCase === 'lower' ? L.toLowerCase() : L;
    const leftRows = left.map((L) =>
        rowForChar(mapChar(L), repetitions, fadePattern),
    );
    const rightRows = right.map((L) =>
        rowForChar(mapChar(L), repetitions, fadePattern),
    );
    return { mode: 'two-column', leftRows, rightRows };
}

/** 与 WorksheetDefinition.generatorConfig 合并后的运行时配置 */
export function mergeLetterTracingConfig(
    base: Partial<LetterTracingGeneratorConfig>,
    overrides: Partial<LetterTracingGeneratorConfig>,
): LetterTracingGeneratorConfig {
    return {
        mode: (overrides.mode ?? base.mode ?? 'single-letter') as LetterTracingMode,
        letterCase: (overrides.letterCase ??
            base.letterCase ??
            'upper') as LetterCaseMode,
        selectedLetter: overrides.selectedLetter ?? base.selectedLetter,
        repetitions: Math.max(
            1,
            (overrides.repetitions ?? base.repetitions ?? 5) as number,
        ),
        fadePattern: (overrides.fadePattern ??
            base.fadePattern ??
            'gradient') as 'gradient' | 'first-only',
    };
}
