import { Response } from 'express';
import { prisma } from '../config/database';
import { AuthRequest } from '../middleware/auth';
import { renderTemplate } from '../lib/templates';
import {
  WHATSAPP_SAMPLE,
  WHATSAPP_KNOWN_KEYS,
  WHATSAPP_APPROVER_REQUEST_EXTRA_KEYS,
  DEFAULT_WHATSAPP_INVITE,
  DEFAULT_WHATSAPP_CHECK_IN,
  DEFAULT_WHATSAPP_REMINDER,
  DEFAULT_WHATSAPP_APPROVER_REQUEST,
} from '../lib/whatsappTemplates';

// Same 4 touchpoints as the email side, kept as identical string literals
// so a future "channel-agnostic automation" surface can iterate one list.
const SUPPORTED_TYPES = ['VISITOR_INVITE', 'CHECK_IN_CONFIRMATION', 'VISITOR_REMINDER', 'APPROVER_REQUEST'] as const;
type SupportedType = typeof SUPPORTED_TYPES[number];

function defaultsFor(type: SupportedType) {
  if (type === 'VISITOR_INVITE') return DEFAULT_WHATSAPP_INVITE;
  if (type === 'CHECK_IN_CONFIRMATION') return DEFAULT_WHATSAPP_CHECK_IN;
  if (type === 'VISITOR_REMINDER') return DEFAULT_WHATSAPP_REMINDER;
  if (type === 'APPROVER_REQUEST') return DEFAULT_WHATSAPP_APPROVER_REQUEST;
  return { body: '' };
}

function variablesFor(type: SupportedType): string[] {
  // Approver-only template surfaces the decision URLs as suggested
  // variables; the other types drop them so the variable picker stays
  // focused on visitor-facing fields.
  const base = (WHATSAPP_KNOWN_KEYS as unknown as string[]).filter((k) => k !== 'approve_url' && k !== 'reject_url');
  if (type === 'APPROVER_REQUEST') {
    return [...base, ...(WHATSAPP_APPROVER_REQUEST_EXTRA_KEYS as unknown as string[])];
  }
  return base;
}

async function ensureDefault(ownerId: string, type: SupportedType) {
  let tpl = await prisma.whatsAppTemplate.findUnique({
    where: { ownerId_type: { ownerId, type } },
  });
  if (!tpl) {
    const d = defaultsFor(type);
    tpl = await prisma.whatsAppTemplate.create({
      data: { ownerId, type, body: d.body },
    });
  }
  return tpl;
}

export async function listWhatsAppTemplates(req: AuthRequest, res: Response) {
  try {
    const templates = await Promise.all(
      SUPPORTED_TYPES.map((t) => ensureDefault(req.ownerId!, t).then((tpl) => ({
        ...tpl,
        variables: variablesFor(t),
      })))
    );
    res.json(templates);
  } catch (error) {
    console.error('listWhatsAppTemplates', error);
    res.status(500).json({ error: 'Failed to fetch WhatsApp templates' });
  }
}

export async function updateWhatsAppTemplate(req: AuthRequest, res: Response) {
  try {
    const type = req.params.type as SupportedType;
    if (!SUPPORTED_TYPES.includes(type)) {
      res.status(400).json({ error: 'Unknown template type' });
      return;
    }
    const { body } = req.body;
    if (typeof body !== 'string') {
      res.status(400).json({ error: 'Body is required' });
      return;
    }
    await ensureDefault(req.ownerId!, type);
    const tpl = await prisma.whatsAppTemplate.update({
      where: { ownerId_type: { ownerId: req.ownerId!, type } },
      data: { body },
    });
    res.json({ ...tpl, variables: variablesFor(type) });
  } catch (error) {
    console.error('updateWhatsAppTemplate', error);
    res.status(500).json({ error: 'Failed to update WhatsApp template' });
  }
}

export async function restoreWhatsAppTemplateDefaults(req: AuthRequest, res: Response) {
  try {
    const type = req.params.type as SupportedType;
    if (!SUPPORTED_TYPES.includes(type)) {
      res.status(400).json({ error: 'Unknown template type' });
      return;
    }
    await ensureDefault(req.ownerId!, type);
    const d = defaultsFor(type);
    const tpl = await prisma.whatsAppTemplate.update({
      where: { ownerId_type: { ownerId: req.ownerId!, type } },
      data: { body: d.body },
    });
    res.json({ ...tpl, variables: variablesFor(type) });
  } catch (error) {
    console.error('restoreWhatsAppTemplateDefaults', error);
    res.status(500).json({ error: 'Failed to restore defaults' });
  }
}

// Renders the saved template against a real visitor and returns the body
// ready to drop into a `wa.me/<digits>?text=` URL. Used by the QR-share
// modal so the click-to-chat pre-fill matches what the owner edited in
// the Templates page (instead of a hard-coded string in the front-end).
//
// Authenticated — the visitor must belong to the caller's workspace.
// The QR-code line is stripped (wa.me can't attach media via deep-link)
// and the QR URL is returned alongside so the UI can surface a download.
export async function renderWhatsAppTemplateForVisitor(req: AuthRequest, res: Response) {
  try {
    const type = req.params.type as SupportedType;
    if (!SUPPORTED_TYPES.includes(type)) {
      res.status(400).json({ error: 'Unknown template type' });
      return;
    }
    const visitorId = req.params.visitorId;
    const visitor = await prisma.visitor.findFirst({
      where: { id: visitorId, ownerId: req.ownerId! },
      select: {
        id: true, name: true, email: true, mobile: true, shortId: true,
        visitDate: true, visitTime: true, notes: true, reasonForVisit: true,
        createdByAdminId: true, assignedAdminId: true, assignedApproverId: true,
      },
    });
    if (!visitor) { res.status(404).json({ error: 'Visitor not found' }); return; }

    const tpl = await prisma.whatsAppTemplate.findUnique({
      where: { ownerId_type: { ownerId: req.ownerId!, type } },
    });
    if (!tpl) { res.status(404).json({ error: 'Template not configured' }); return; }

    // Render the body with {{qr_code}} interpolated INLINE — this endpoint
    // feeds the `wa.me` click-to-chat deep link, which is text-only. Keeping
    // the URL inside the body means the visitor sees a tappable link
    // wherever the author placed {{qr_code}} in their template, and the
    // recipient opens the QR PNG in their phone's browser.
    //
    // The send pipeline still uses `extractQrAttachment` separately so a
    // real provider can attach the QR as media when one is wired up.
    const { visitorVars } = await import('../lib/whatsappSend');
    const vars = await visitorVars(req.ownerId!, visitor as any, req);
    const body = renderTemplate(tpl.body, vars as any);
    res.json({ body, qrUrl: vars.qr_code });
  } catch (error) {
    console.error('renderWhatsAppTemplateForVisitor', error);
    res.status(500).json({ error: 'Failed to render template' });
  }
}

export async function previewWhatsAppTemplate(req: AuthRequest, res: Response) {
  try {
    const type = req.params.type as SupportedType;
    if (!SUPPORTED_TYPES.includes(type)) {
      res.status(400).json({ error: 'Unknown template type' });
      return;
    }
    const { body } = req.body;
    if (typeof body !== 'string') {
      res.status(400).json({ error: 'Body is required' });
      return;
    }
    // Mirror the send-pipeline behaviour: {{qr_code}} doesn't render in the
    // text — its line is stripped and the QR URL is returned separately so
    // the editor's preview pane can show the image as a media attachment.
    const hasQr = /\{\{\s*qr_code\s*\}\}/.test(body);
    const stripped = hasQr
      ? body.split('\n').filter((line) => !/\{\{\s*qr_code\s*\}\}/.test(line)).join('\n').replace(/\n{3,}/g, '\n\n').replace(/^\n+|\n+$/g, '')
      : body;
    const renderedBody = renderTemplate(stripped, WHATSAPP_SAMPLE as any);
    res.json({ body: renderedBody, qrUrl: hasQr ? WHATSAPP_SAMPLE.qr_code : undefined });
  } catch (error) {
    console.error('previewWhatsAppTemplate', error);
    res.status(500).json({ error: 'Failed to render preview' });
  }
}
