import { Router } from 'express';
import axios from 'axios';
import jwt from 'jsonwebtoken';
import { db } from '../lib/db.js';

export const authRouter = Router();

const SPOTIFY_CLIENT_ID = process.env.SPOTIFY_CLIENT_ID || '';
const SPOTIFY_CLIENT_SECRET = process.env.SPOTIFY_CLIENT_SECRET || '';
const REDIRECT_URI = process.env.REDIRECT_URI || 'http://localhost:3000/callback';
const JWT_SECRET = process.env.JWT_SECRET || 'dev-secret-change';

authRouter.post('/exchange', async (req, res) => {
  try {
    const { code } = req.body as { code?: string };
    if (!code) return res.status(400).json({ error: 'Missing code' });

    const tokenResp = await axios.post(
      'https://accounts.spotify.com/api/token',
      new URLSearchParams({
        grant_type: 'authorization_code',
        code,
        redirect_uri: REDIRECT_URI,
      }),
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          Authorization: `Basic ${Buffer.from(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`).toString('base64')}`,
        },
      }
    );

    const { access_token, refresh_token, expires_in } = tokenResp.data as {
      access_token: string;
      refresh_token: string;
      expires_in: number;
    };

    const meResp = await axios.get('https://api.spotify.com/v1/me', {
      headers: { Authorization: `Bearer ${access_token}` },
    });
    const profile = meResp.data as any;

    const now = Date.now();
    const tokenExpiresAt = now + expires_in * 1000 - 60_000; // refresh a bit early

    db.db
      .prepare(
        `INSERT INTO users (id, display_name, email, avatar_url, country, product, created_at, updated_at, access_token, refresh_token, token_expires_at)
         VALUES (@id, @display_name, @email, @avatar_url, @country, @product, @created_at, @updated_at, @access_token, @refresh_token, @token_expires_at)
         ON CONFLICT(id) DO UPDATE SET
           display_name=excluded.display_name,
           email=excluded.email,
           avatar_url=excluded.avatar_url,
           country=excluded.country,
           product=excluded.product,
           updated_at=excluded.updated_at,
           access_token=excluded.access_token,
           refresh_token=excluded.refresh_token,
           token_expires_at=excluded.token_expires_at`
      )
      .run({
        id: profile.id,
        display_name: profile.display_name,
        email: profile.email,
        avatar_url: profile.images?.[0]?.url || null,
        country: profile.country,
        product: profile.product,
        created_at: now,
        updated_at: now,
        access_token,
        refresh_token,
        token_expires_at: tokenExpiresAt,
      });

    const jwtToken = jwt.sign({ uid: profile.id }, JWT_SECRET, { expiresIn: '30d' });
    // Return Spotify tokens to enable client-side playback controls
    res.json({ token: jwtToken, uid: profile.id, access_token, refresh_token, expires_in });
  } catch (err: any) {
    const detail = err?.response?.data || err?.message || 'Unknown error';
    console.error('Auth exchange error:', detail);
    res.status(500).json({ error: 'Auth exchange failed', detail });
  }
});

authRouter.post('/refresh', async (req, res) => {
  try {
    const { uid } = req.body as { uid?: string };
    if (!uid) return res.status(400).json({ error: 'Missing uid' });
    const row = db.db.prepare('SELECT refresh_token FROM users WHERE id = ?').get(uid) as { refresh_token?: string } | undefined;
    if (!row?.refresh_token) return res.status(404).json({ error: 'User not found' });

    const tokenResp = await axios.post(
      'https://accounts.spotify.com/api/token',
      new URLSearchParams({ grant_type: 'refresh_token', refresh_token: row.refresh_token }),
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          Authorization: `Basic ${Buffer.from(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`).toString('base64')}`,
        },
      }
    );

    const { access_token, expires_in } = tokenResp.data as { access_token: string; expires_in: number };
    const tokenExpiresAt = Date.now() + expires_in * 1000 - 60_000;
    db.db.prepare('UPDATE users SET access_token=?, token_expires_at=?, updated_at=? WHERE id=?').run(access_token, tokenExpiresAt, Date.now(), uid);
    res.json({ ok: true });
  } catch (err: any) {
    console.error(err.response?.data || err.message);
    res.status(500).json({ error: 'Refresh failed' });
  }
});


