import Database from '@tauri-apps/plugin-sql';
import { FlashcardSet, Flashcard } from '@/lib/mockData';

// We shadow the mock types or use them if they match.
// Ideally we should import from a shared types file, but mockData has them.
// Let's ensure we return compatible types.

const DB_NAME = 'sqlite:flashcards.db';

export const getDb = async () => {
    return await Database.load(DB_NAME);
}

// Sets
export const createFlashcardSet = async (title: string, topic: string, color: string): Promise<string> => {
    const db = await getDb();
    const id = crypto.randomUUID();
    await db.execute(
        'INSERT INTO flashcard_sets (id, title, topic, color) VALUES ($1, $2, $3, $4)',
        [id, title, topic, color]
    );
    return id;
}

export const getFlashcardSets = async (): Promise<FlashcardSet[]> => {
    const db = await getDb();
    // We need to join with cards to get the count or fetch cards separately.
    // The mock type `FlashcardSet` includes `cards: Flashcard[]`.
    // Populating that fully might be expensive if there are many cards.
    // For the list view, we just need the count usually, but the type requires `cards`.
    // Let's fetch all sets and then for each set, fetch its cards.
    // Or we can just fetch the count and return a partial object if the UI supports it,
    // but the UI expects `FlashcardSet`.
    // Let's fetch all data for now as it's a desktop app with local DB.

    const sets: any[] = await db.select('SELECT * FROM flashcard_sets ORDER BY created_at DESC');

    // For each set, fetch cards
    const results: FlashcardSet[] = [];
    for (const set of sets) {
        const cards: Flashcard[] = await db.select('SELECT * FROM flashcards WHERE set_id = $1', [set.id]);
        results.push({
            id: set.id,
            title: set.title,
            topic: set.topic,
            color: set.color,
            cards: cards
        });
    }
    return results;
}

export const deleteFlashcardSet = async (id: string) => {
    const db = await getDb();
    await db.execute('DELETE FROM flashcard_sets WHERE id = $1', [id]);
}

export const getFlashcardSetById = async (id: string): Promise<FlashcardSet | null> => {
    const db = await getDb();
    const sets: any[] = await db.select('SELECT * FROM flashcard_sets WHERE id = $1', [id]);
    if (sets.length === 0) return null;

    const set = sets[0];
    const cards: Flashcard[] = await db.select('SELECT * FROM flashcards WHERE set_id = $1', [set.id]);

    return {
        id: set.id,
        title: set.title,
        topic: set.topic,
        color: set.color,
        cards: cards
    };
}

// Cards
export const createFlashcard = async (setId: string, front: string, back: string) => {
    const db = await getDb();
    const id = crypto.randomUUID();
    await db.execute(
        'INSERT INTO flashcards (id, set_id, front, back, status) VALUES ($1, $2, $3, $4, $5)',
        [id, setId, front, back, 'new']
    );
    return id;
}

export const updateFlashcard = async (id: string, front: string, back: string) => {
    const db = await getDb();
    await db.execute(
        'UPDATE flashcards SET front = $1, back = $2 WHERE id = $3',
        [front, back, id]
    );
}

export const deleteFlashcard = async (id: string) => {
    const db = await getDb();
    await db.execute('DELETE FROM flashcards WHERE id = $1', [id]);
}

export const updateFlashcardStatus = async (id: string, status: 'new' | 'learning' | 'review') => {
    const db = await getDb();
    await db.execute(
        'UPDATE flashcards SET status = $1 WHERE id = $2',
        [status, id]
    );
}

// Smart Stories

export interface StoryVocabItem {
    word: string;
    translation: string;
}

export interface GeneratedStory {
    id: string;
    title: string;
    content: string;
    difficulty: string;
    topic: string;
    vocab_json: string; // Stored as JSON string
    created_at?: string;
    vocab?: StoryVocabItem[]; // Parsed helper
}

export const createStory = async (story: Omit<GeneratedStory, 'id' | 'created_at' | 'vocab'>) => {
    const db = await getDb();
    const id = crypto.randomUUID();
    await db.execute(
        'INSERT INTO smart_stories (id, title, content, difficulty, topic, vocab_json) VALUES ($1, $2, $3, $4, $5, $6)',
        [id, story.title, story.content, story.difficulty, story.topic, story.vocab_json]
    );
    return id;
}

export const getStories = async (): Promise<GeneratedStory[]> => {
    const db = await getDb();
    const stories: GeneratedStory[] = await db.select('SELECT * FROM smart_stories ORDER BY created_at DESC');
    return stories.map(s => ({
        ...s,
        vocab: JSON.parse(s.vocab_json)
    }));
}

export const getStoryById = async (id: string): Promise<GeneratedStory | null> => {
    const db = await getDb();
    const stories: GeneratedStory[] = await db.select('SELECT * FROM smart_stories WHERE id = $1', [id]);
    if (stories.length === 0) return null;
    const s = stories[0];
    return {
        ...s,
        vocab: JSON.parse(s.vocab_json)
    };
}

export const deleteStory = async (id: string) => {
    const db = await getDb();
    await db.execute('DELETE FROM smart_stories WHERE id = $1', [id]);
}
