const express = require('express');
const router = express.Router();
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const { supabase } = require('../config/supabase');
const { sendOTPEmail } = require('../services/email');

/**
 * POST /api/auth/request-otp
 * Отправляет OTP код на email
 * Если пользователя нет - создаёт нового
 */
router.post('/request-otp', async (req, res) => {
  try {
    const { email } = req.body;

    if (!email || !email.includes('@')) {
      return res.status(400).json({ error: 'Valid email is required' });
    }

    const normalizedEmail = email.toLowerCase().trim();

    // Проверяем существует ли пользователь в таблице users
    const { data: existingUser } = await supabase
      .from('users')
      .select('id, email, first_name')
      .eq('email', normalizedEmail)
      .single();

    let isNewUser = !existingUser;
    let userId = existingUser?.id;

    // Если пользователя нет - создаём
    if (isNewUser) {
      const { data: newUser, error: createError } = await supabase
        .from('users')
        .insert({
          email: normalizedEmail
        })
        .select()
        .single();

      if (createError) {
        console.error('Create user error:', createError);
        return res.status(500).json({ error: 'Failed to create user' });
      }

      userId = newUser.id;
    }

    // Генерируем 6-значный OTP код
    const otpCode = crypto.randomInt(100000, 999999).toString();
    const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 минут

    // Удаляем старые неиспользованные коды для этого email
    await supabase
      .from('otp_codes')
      .delete()
      .eq('email', normalizedEmail)
      .is('used_at', null);

    // Сохраняем новый код
    const { error: otpError } = await supabase
      .from('otp_codes')
      .insert({
        email: normalizedEmail,
        code: otpCode,
        expires_at: expiresAt.toISOString()
      });

    if (otpError) {
      console.error('OTP save error:', otpError);
      return res.status(500).json({ error: 'Failed to generate OTP' });
    }

    // Отправляем email
    console.log(`[OTP] Sending code ${otpCode} to ${normalizedEmail}`);
    const emailSent = await sendOTPEmail(normalizedEmail, otpCode, existingUser?.first_name);
    console.log(`[OTP] Email sent result: ${emailSent}`);

    if (!emailSent) {
      return res.status(500).json({ error: 'Failed to send email' });
    }

    res.json({
      success: true,
      message: 'OTP sent to email',
      isNewUser
    });

  } catch (error) {
    console.error('Request OTP error:', error);
    res.status(500).json({ error: error.message });
  }
});

/**
 * POST /api/auth/verify-otp
 * Проверяет OTP код и возвращает JWT токен
 */
router.post('/verify-otp', async (req, res) => {
  try {
    const { email, code } = req.body;

    if (!email || !code) {
      return res.status(400).json({ error: 'Email and code are required' });
    }

    const normalizedEmail = email.toLowerCase().trim();

    // Ищем валидный OTP (used_at IS NULL означает неиспользованный)
    const { data: otpRecord, error: otpError } = await supabase
      .from('otp_codes')
      .select('*')
      .eq('email', normalizedEmail)
      .eq('code', code)
      .is('used_at', null)
      .gt('expires_at', new Date().toISOString())
      .single();

    if (otpError || !otpRecord) {
      return res.status(401).json({ error: 'Invalid or expired code' });
    }

    // Помечаем код как использованный
    await supabase
      .from('otp_codes')
      .update({ used_at: new Date().toISOString() })
      .eq('id', otpRecord.id);

    // Получаем пользователя из таблицы users
    const { data: user, error: userError } = await supabase
      .from('users')
      .select('*')
      .eq('email', normalizedEmail)
      .single();

    if (userError || !user) {
      return res.status(404).json({ error: 'User not found' });
    }

    // Обновляем last_login_at
    await supabase
      .from('users')
      .update({ last_login_at: new Date().toISOString() })
      .eq('id', user.id);

    // Получаем beneficiaries через user_access
    const { data: accessRecords } = await supabase
      .from('user_access')
      .select(`
        beneficiary_id,
        role,
        granted_at,
        beneficiaries:beneficiary_id (
          id,
          email,
          first_name,
          last_name,
          phone,
          address_street,
          address_city,
          address_zip,
          address_state,
          address_country
        )
      `)
      .eq('accessor_id', user.id);

    // Форматируем beneficiaries
    const beneficiaries = (accessRecords || []).map(record => ({
      id: record.beneficiary_id,
      role: record.role,
      grantedAt: record.granted_at,
      ...record.beneficiaries
    }));

    // Генерируем JWT токен
    const token = jwt.sign(
      {
        userId: user.id,
        email: user.email
      },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
    );

    res.json({
      success: true,
      token,
      user: {
        id: user.id,
        email: user.email,
        firstName: user.first_name,
        lastName: user.last_name,
        phone: user.phone,
        role: user.role || 'user'
      },
      beneficiaries
    });

  } catch (error) {
    console.error('Verify OTP error:', error);
    res.status(500).json({ error: error.message });
  }
});

/**
 * GET /api/auth/me
 * Возвращает текущего пользователя по JWT токену
 */
router.get('/me', async (req, res) => {
  try {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return res.status(401).json({ error: 'No token provided' });
    }

    const token = authHeader.split(' ')[1];

    let decoded;
    try {
      decoded = jwt.verify(token, process.env.JWT_SECRET);
    } catch (err) {
      return res.status(401).json({ error: 'Invalid token' });
    }

    // Получаем пользователя из таблицы users
    const { data: user, error } = await supabase
      .from('users')
      .select('*')
      .eq('id', decoded.userId)
      .single();

    if (error || !user) {
      return res.status(404).json({ error: 'User not found' });
    }

    // Получаем beneficiaries через user_access
    const { data: accessRecords } = await supabase
      .from('user_access')
      .select(`
        beneficiary_id,
        role,
        granted_at,
        beneficiaries:beneficiary_id (
          id,
          email,
          first_name,
          last_name,
          phone,
          address_street,
          address_city,
          address_zip,
          address_state,
          address_country
        )
      `)
      .eq('accessor_id', user.id);

    // Форматируем beneficiaries
    const beneficiaries = (accessRecords || []).map(record => ({
      id: record.beneficiary_id,
      role: record.role,
      grantedAt: record.granted_at,
      ...record.beneficiaries
    }));

    res.json({
      user: {
        id: user.id,
        email: user.email,
        firstName: user.first_name,
        lastName: user.last_name,
        phone: user.phone,
        role: user.role || 'user'
      },
      beneficiaries
    });

  } catch (error) {
    console.error('Get me error:', error);
    res.status(500).json({ error: error.message });
  }
});

/**
 * PATCH /api/auth/profile
 * Обновляет профиль пользователя
 */
router.patch('/profile', async (req, res) => {
  try {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return res.status(401).json({ error: 'No token provided' });
    }

    const token = authHeader.split(' ')[1];
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    const { firstName, lastName, phone, addressStreet, addressCity, addressZip, addressState, addressCountry } = req.body;

    const updateData = {
      updated_at: new Date().toISOString()
    };

    if (firstName !== undefined) updateData.first_name = firstName;
    if (lastName !== undefined) updateData.last_name = lastName;
    if (phone !== undefined) updateData.phone = phone;
    if (addressStreet !== undefined) updateData.address_street = addressStreet;
    if (addressCity !== undefined) updateData.address_city = addressCity;
    if (addressZip !== undefined) updateData.address_zip = addressZip;
    if (addressState !== undefined) updateData.address_state = addressState;
    if (addressCountry !== undefined) updateData.address_country = addressCountry;

    const { data: user, error } = await supabase
      .from('users')
      .update(updateData)
      .eq('id', decoded.userId)
      .select()
      .single();

    if (error) {
      return res.status(500).json({ error: 'Failed to update profile' });
    }

    res.json({
      success: true,
      user: {
        id: user.id,
        email: user.email,
        firstName: user.first_name,
        lastName: user.last_name,
        phone: user.phone,
        addressStreet: user.address_street,
        addressCity: user.address_city,
        addressZip: user.address_zip,
        addressState: user.address_state,
        addressCountry: user.address_country
      }
    });

  } catch (error) {
    console.error('Update profile error:', error);
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;
