import { Router } from 'express';
import { db } from '../lib/db.js';
import { addSseClient, sendEvent, sendToBoth } from '../lib/events.js';
import { requireAuth } from '../middleware/auth.js';
export const partnersRouter = Router();
// Send a partner request (not via link) by target uid
partnersRouter.post('/request', requireAuth, (req, res) => {
    const { toUid } = req.body;
    const fromUid = req.user?.uid;
    if (!fromUid || !toUid || fromUid === toUid)
        return res.status(400).json({ error: 'Invalid uids' });
    const now = Date.now();
    try {
        db.db
            .prepare(`INSERT INTO friend_requests (from_user_id, to_user_id, status, created_at, updated_at)
         VALUES (?, ?, 'pending', ?, ?)`)
            .run(fromUid, toUid, now, now);
        // Notify the recipient about a new incoming request
        sendEvent(toUid, { type: 'partner:request', fromUserId: fromUid, at: now });
        res.json({ ok: true });
    }
    catch (e) {
        if (e && String(e.message).includes('UNIQUE')) {
            return res.status(409).json({ error: 'Request already exists' });
        }
        throw e;
    }
});
// List incoming requests for a user
partnersRouter.get('/requests/:uid', requireAuth, (req, res) => {
    const { uid } = req.params;
    if (!req.user || req.user.uid !== uid)
        return res.status(403).json({ error: 'Forbidden' });
    const rows = db.db
        .prepare("SELECT id, from_user_id, to_user_id, status, created_at FROM friend_requests WHERE to_user_id = ? AND status = 'pending' ORDER BY created_at DESC")
        .all(uid);
    res.json(rows);
});
// Accept a request
partnersRouter.post('/requests/:id/accept', requireAuth, (req, res) => {
    const { id } = req.params;
    const reqRow = db.db.prepare('SELECT * FROM friend_requests WHERE id = ?').get(id);
    if (!reqRow)
        return res.status(404).json({ error: 'Not found' });
    if (!req.user || req.user.uid !== reqRow.to_user_id)
        return res.status(403).json({ error: 'Forbidden' });
    const now = Date.now();
    const userA = reqRow.from_user_id < reqRow.to_user_id ? reqRow.from_user_id : reqRow.to_user_id;
    const userB = reqRow.from_user_id < reqRow.to_user_id ? reqRow.to_user_id : reqRow.from_user_id;
    const txn = db.db.transaction(() => {
        db.db.prepare("UPDATE friend_requests SET status='accepted', updated_at=? WHERE id=?").run(now, id);
        db.db.prepare('INSERT OR IGNORE INTO friendships (user_a_id, user_b_id, created_at) VALUES (?, ?, ?)').run(userA, userB, now);
    });
    txn();
    // Notify both users of partnership established
    sendToBoth(userA, userB, { type: 'partner:connected', a: userA, b: userB, at: now });
    res.json({ ok: true });
});
// Decline a request
partnersRouter.post('/requests/:id/decline', requireAuth, (req, res) => {
    const { id } = req.params;
    const now = Date.now();
    const reqRow = db.db.prepare('SELECT * FROM friend_requests WHERE id = ?').get(id);
    if (!reqRow)
        return res.status(404).json({ error: 'Not found' });
    if (!req.user || req.user.uid !== reqRow.to_user_id)
        return res.status(403).json({ error: 'Forbidden' });
    db.db.prepare("UPDATE friend_requests SET status='declined', updated_at=? WHERE id=?").run(now, id);
    // Notify requester that their request was declined
    sendEvent(reqRow.from_user_id, { type: 'partner:declined', byUserId: reqRow.to_user_id, requestId: reqRow.id, at: now });
    res.json({ ok: true });
});
// Check partnership between two users
partnersRouter.get('/status', (req, res) => {
    const { a, b } = req.query;
    if (!a || !b)
        return res.status(400).json({ error: 'Missing params' });
    const [userA, userB] = a < b ? [a, b] : [b, a];
    const exists = db.db
        .prepare('SELECT 1 FROM friendships WHERE user_a_id=? AND user_b_id=?')
        .get(userA, userB);
    res.json({ partnered: !!exists });
});
// Fetch partner for a user (if any)
partnersRouter.get('/partner/:uid', requireAuth, (req, res) => {
    const { uid } = req.params;
    if (!req.user || req.user.uid !== uid)
        return res.status(403).json({ error: 'Forbidden' });
    const row = db.db
        .prepare(`SELECT CASE WHEN user_a_id = ? THEN user_b_id ELSE user_a_id END as partner_id
       FROM friendships
       WHERE user_a_id = ? OR user_b_id = ?
       LIMIT 1`)
        .get(uid, uid, uid);
    if (!row?.partner_id)
        return res.json({ partnerId: null });
    return res.json({ partnerId: row.partner_id });
});
// SSE: subscribe to partner events for authed user
partnersRouter.get('/events/:uid', requireAuth, (req, res) => {
    const { uid } = req.params;
    if (!req.user || req.user.uid !== uid)
        return res.status(403).json({ error: 'Forbidden' });
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');
    res.flushHeaders?.();
    const cleanup = addSseClient(uid, res);
    req.on('close', cleanup);
});
// Remove an existing partnership between the authed user and a specific partner
partnersRouter.post('/remove', requireAuth, (req, res) => {
    const { partnerId } = req.body;
    const uid = req.user?.uid;
    if (!uid || !partnerId || uid === partnerId)
        return res.status(400).json({ error: 'Invalid partnerId' });
    const userA = uid < partnerId ? uid : partnerId;
    const userB = uid < partnerId ? partnerId : uid;
    const existing = db.db
        .prepare('SELECT id FROM friendships WHERE user_a_id=? AND user_b_id=?')
        .get(userA, userB);
    if (!existing?.id)
        return res.status(404).json({ error: 'No active partnership' });
    try {
        const txn = db.db.transaction(() => {
            db.db.prepare('DELETE FROM friendships WHERE user_a_id=? AND user_b_id=?').run(userA, userB);
            // Remove any historical or pending requests between the two users so they can re-invite
            db.db
                .prepare('DELETE FROM friend_requests WHERE (from_user_id=? AND to_user_id=?) OR (from_user_id=? AND to_user_id=?)')
                .run(uid, partnerId, partnerId, uid);
        });
        txn();
        // Notify both users of disconnection
        sendToBoth(userA, userB, { type: 'partner:disconnected', a: userA, b: userB, at: Date.now() });
        return res.json({ ok: true });
    }
    catch (e) {
        return res.status(500).json({ error: 'Failed to remove partnership' });
    }
});
// Clear any existing partnership for the authed user (fallback helper)
partnersRouter.post('/clear', requireAuth, (req, res) => {
    const { userId } = req.body;
    const uid = req.user?.uid;
    if (!uid || !userId || uid !== userId)
        return res.status(403).json({ error: 'Forbidden' });
    try {
        // Find all partners (normally only one) and delete links + requests
        const partners = db.db
            .prepare('SELECT CASE WHEN user_a_id = ? THEN user_b_id ELSE user_a_id END as partner_id FROM friendships WHERE user_a_id = ? OR user_b_id = ?')
            .all(uid, uid, uid);
        const txn = db.db.transaction(() => {
            db.db.prepare('DELETE FROM friendships WHERE user_a_id=? OR user_b_id=?').run(uid, uid);
            for (const row of partners) {
                db.db
                    .prepare('DELETE FROM friend_requests WHERE (from_user_id=? AND to_user_id=?) OR (from_user_id=? AND to_user_id=?)')
                    .run(uid, row.partner_id, row.partner_id, uid);
            }
        });
        txn();
        // Notify the user and any former partners
        for (const row of partners) {
            const a = uid < row.partner_id ? uid : row.partner_id;
            const b = uid < row.partner_id ? row.partner_id : uid;
            sendToBoth(a, b, { type: 'partner:disconnected', a, b, at: Date.now() });
        }
        return res.json({ ok: true });
    }
    catch (e) {
        return res.status(500).json({ error: 'Failed to clear partnership' });
    }
});
