import dotenv from 'dotenv';
import path from 'path';

// Load env from project root
dotenv.config({ path: path.join(__dirname, '../../.env') });
import express from 'express';
import cors from 'cors';
import authRoutes from './routes/auth';
import exerciseRoutes from './routes/exercises';
import sessionRoutes from './routes/sessions';
import planRoutes from './routes/plans';
import aiRoutes from './routes/ai';
import weightRoutes from './routes/weight';
import bookmarksRoutes from './routes/bookmarks';

import bcrypt from 'bcryptjs';
import { PrismaClient } from '@prisma/client';
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
import BetterSqlite3 from 'better-sqlite3';

const app = express();

// -------------------------------------------------------------------
// Ensure a default admin user exists on startup
// -------------------------------------------------------------------
async function ensureAdminUser() {
    const mode = process.env.APP_MODE || 'dev';
    let adminEmail, adminPassword;

    switch (mode) {
        case 'test':
            adminEmail = process.env.ADMIN_EMAIL_TEST;
            adminPassword = process.env.ADMIN_PASSWORD_TEST;
            break;
        case 'prod':
            adminEmail = process.env.ADMIN_EMAIL_PROD;
            adminPassword = process.env.ADMIN_PASSWORD_PROD;
            break;
        case 'dev':
        default:
            adminEmail = process.env.ADMIN_EMAIL_DEV;
            adminPassword = process.env.ADMIN_PASSWORD_DEV;
            break;
    }

    if (!adminEmail || !adminPassword) {
        console.warn(`⚠️  Admin credentials for mode ${mode} not found in .env. Skipping default admin creation.`);
        return;
    }

    // Use the singleton prisma client
    const prisma = (await import('./lib/prisma')).default;

    // Check for existing admin
    const existingAdmin = await prisma.user.findFirst({
        where: { role: 'ADMIN' },
    });

    const { AuthService } = await import('./services/auth.service');

    if (existingAdmin) {
        if (existingAdmin.email === adminEmail) {
            console.info(`✅  Admin user already exists (email: ${existingAdmin.email})`);
        } else {
            console.info(`ℹ️  Admin user exists but with different email: ${existingAdmin.email}. Expected: ${adminEmail}`);
        }
        // Even if admin exists, ensure exercises are seeded (will skip if already has them)
        await AuthService.seedDefaultExercises(existingAdmin.id, 'en');
        await prisma.$disconnect();
        return;
    }

    // Create admin user
    const hashed = await bcrypt.hash(adminPassword, 10);
    const admin = await prisma.user.create({
        data: {
            email: adminEmail,
            password: hashed,
            role: 'ADMIN',
            profile: { create: { weight: 70, language: 'en' } },
        },
    });

    // Seed exercises for new admin
    await AuthService.seedDefaultExercises(admin.id, 'en');

    console.info(`✅  Admin user created and exercises seeded (email: ${adminEmail})`);
    await prisma.$disconnect();
}

const PORT = process.env.PORT || 3001;

app.use(cors());
app.use(express.json());

// Routes
app.use('/api/auth', authRoutes);
app.use('/api/exercises', exerciseRoutes);
app.use('/api/sessions', sessionRoutes);
app.use('/api/plans', planRoutes);
app.use('/api/ai', aiRoutes);
app.use('/api/weight', weightRoutes);
app.use('/api/bookmarks', bookmarksRoutes);


// Serve frontend in production
if (process.env.NODE_ENV === 'production') {
    const distPath = path.join(__dirname, '../../dist');
    app.use(express.static(distPath));

    app.get('*all', (req, res) => {
        if (!req.path.startsWith('/api')) {
            res.sendFile(path.join(distPath, 'index.html'));
        } else {
            res.status(404).json({ error: 'API route not found' });
        }
    });
} else {
    app.get('/', (req, res) => {
        res.send('GymFlow AI API is running (Dev Mode)');
    });
}

ensureAdminUser()
    .catch((e) => {
        console.error('❌  Failed to ensure admin user:', e);
        process.exit(1);
    })
    .finally(() => {
        app.listen(PORT, () => {
            console.log(`Server running on port ${PORT}`);
        });
    });
