const express = require('express');
const path = require('path');
const botLogic = require('./botLogic');
const configManager = require('./configManager');
const { getTemporalClient } = require('./temporalClient');
const crypto = require('crypto');
const app = express();
const port = 3000;

app.use(express.json());
// Serve static files
app.use(express.static(path.join(__dirname, '../'), {
    setHeaders: (res, path) => {
        if (path.endsWith('.html')) {
            res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
            res.setHeader('Pragma', 'no-cache');
            res.setHeader('Expires', '0');
        }
    }
}));

// Primary Routes
app.get('/', (req, res) => {
    res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    res.sendFile(path.join(__dirname, '../login.html'));
});

app.get('/admin', (req, res) => {
    res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    res.sendFile(path.join(__dirname, '../admin.html'));
});

app.get('/dashboard', (req, res) => {
    res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    res.sendFile(path.join(__dirname, '../dashboard.html'));
});

// Multi-tenant Config API
app.get('/api/config/:tenantId', (req, res) => {
    const config = configManager.getTenantConfig(req.params.tenantId);
    res.json(config);
});

// Official Twilio Webhook parsing middleware
app.use(express.urlencoded({ extended: true }));

// WhatsApp Webhook (Twilio)
app.post('/whatsapp/webhook', async (req, res) => {
    // Twilio sends urlencoded fields: From, Body
    // Or our mock sends json: from, body
    const from = req.body.From || req.body.from;
    const body = req.body.Body || req.body.body;
    
    console.log(`[WhatsApp Webhook] Received message from ${from}: ${body}`);
    
    if (!from || !body) {
        return res.status(400).send("Missing from or body");
    }

    try {
        const temporalClient = await getTemporalClient();
        // Use the phone number as the unique Workflow ID
        const workflowId = `booking-${from.replace(/[^a-zA-Z0-9]/g, '')}`;
        
        let handle;
        try {
            handle = temporalClient.workflow.getHandle(workflowId);
            const desc = await handle.describe();
            if (desc.status.name === 'RUNNING') {
                // Ongoing conversation! Send a signal with the new message
                console.log(`[WhatsApp Webhook] Signaling existing workflow ${workflowId}`);
                await handle.signal('receive_message', body);
                
                // Twilio expects a valid TwiML response. Empty response means no immediate automated reply.
                // Our Temporal worker will asynchronously send a reply back via Twilio API.
                res.type('text/xml').send('<Response></Response>');
                return;
            }
        } catch (err) {
            // Workflow does not exist. We will start a new one below.
        }

        console.log(`[WhatsApp Webhook] Starting new AppointmentBookingWorkflow for ${from}`);
        await temporalClient.workflow.start('AppointmentBookingWorkflow', {
            args: [body, from],
            taskQueue: 'curaflow-tasks',
            workflowId: workflowId,
        });

        res.type('text/xml').send('<Response></Response>');
    } catch (err) {
        console.error('[WhatsApp Webhook] Error processing message:', err);
        res.status(500).send('Internal Server Error');
    }
});

// AI Scribe Endpoints
app.post('/api/ai/scribe/start', async (req, res) => {
    try {
        const { dictation } = req.body;
        if (!dictation) return res.status(400).json({ error: 'Dictation is required' });

        const temporalClient = await getTemporalClient();
        const jobId = `scribe-${crypto.randomUUID()}`;

        console.log(`[AI Scribe] Starting job ${jobId} for dictation of length ${dictation.length}`);
        
        // Start the workflow asynchronously
        await temporalClient.workflow.start('ClinicalIntakeWorkflow', {
            args: [dictation],
            taskQueue: 'curaflow-tasks',
            workflowId: jobId,
        });

        res.json({ success: true, jobId });
    } catch (err) {
        console.error('[AI Scribe] Start Error:', err);
        res.status(500).json({ error: 'Failed to start AI Scribe job' });
    }
});

app.get('/api/ai/scribe/status/:jobId', async (req, res) => {
    try {
        const { jobId } = req.params;
        const temporalClient = await getTemporalClient();
        
        const handle = temporalClient.workflow.getHandle(jobId);
        const description = await handle.describe();

        // Check if completed
        if (description.status.name === 'COMPLETED') {
            const result = await handle.result();
            return res.json({ status: 'COMPLETED', result });
        } else if (description.status.name === 'FAILED') {
            return res.json({ status: 'FAILED' });
        }

        return res.json({ status: description.status.name });
    } catch (err) {
        // If not found or error
        console.error(`[AI Scribe] Status Error for ${req.params.jobId}:`, err);
        res.status(500).json({ error: 'Failed to get job status' });
    }
});

// Lab Watcher Endpoints
app.post('/api/ai/lab/watch/start', async (req, res) => {
    try {
        const { patientId, baselineData } = req.body;
        if (!patientId) return res.status(400).json({ error: 'Patient ID is required' });

        const temporalClient = await getTemporalClient();
        const workflowId = `lab-watcher-${patientId}`;

        // Ensure we don't start it twice if it's already running
        try {
            const handle = temporalClient.workflow.getHandle(workflowId);
            const desc = await handle.describe();
            if (desc.status.name === 'RUNNING') {
                return res.json({ success: true, message: 'Watcher already running' });
            }
        } catch (e) {
            // Not found, so we proceed to start it
        }

        await temporalClient.workflow.start('LabResultWatcherWorkflow', {
            args: [baselineData || { baseline: "Patient is healthy", medications: [] }],
            taskQueue: 'curaflow-tasks',
            workflowId: workflowId,
        });

        res.json({ success: true });
    } catch (err) {
        console.error('[AI Lab Watcher] Start Error:', err);
        res.status(500).json({ error: 'Failed to start AI Lab Watcher' });
    }
});

app.post('/api/ai/lab/result/:patientId', async (req, res) => {
    try {
        const { patientId } = req.params;
        const { result } = req.body;
        if (!result) return res.status(400).json({ error: 'Lab result string is required' });

        const temporalClient = await getTemporalClient();
        const workflowId = `lab-watcher-${patientId}`;
        const handle = temporalClient.workflow.getHandle(workflowId);

        await handle.signal('add_lab_result', result);
        res.json({ success: true });
    } catch (err) {
        console.error(`[AI Lab Watcher] Signal Error for ${req.params.patientId}:`, err);
        res.status(500).json({ error: 'Failed to send lab result to AI Watcher' });
    }
});

app.get('/api/ai/lab/alerts/:patientId', async (req, res) => {
    try {
        const { patientId } = req.params;
        const temporalClient = await getTemporalClient();
        const workflowId = `lab-watcher-${patientId}`;
        
        try {
            const handle = temporalClient.workflow.getHandle(workflowId);
            const alerts = await handle.query('get_alerts');
            res.json({ success: true, alerts });
        } catch (e) {
            // Workflow might not be running
            res.json({ success: true, alerts: [] });
        }
    } catch (err) {
        console.error(`[AI Lab Watcher] Query Error for ${req.params.patientId}:`, err);
        res.status(500).json({ error: 'Failed to fetch alerts' });
    }
});

app.listen(port, '0.0.0.0', () => {
    console.log(`Curio WhatsApp Mock Server running at http://0.0.0.0:${port}`);
});
