import { Router } from 'express';
import { authenticate } from '../../../middleware/auth.middleware';
import { requireRole } from '../../../middleware/rbac.middleware';
import { validate } from '../../../middleware/validate';
import { smsContactsService } from './sms-contacts.service';
import { createContactListSchema, updateContactListSchema, createContactEntrySchema, bulkAddEntriesSchema } from './sms-contacts.schemas';
import { BROADCAST_ROLES } from '../../../utils/roles';

const router = Router();

// All routes require authentication + broadcast admin role
router.use(authenticate, requireRole(...BROADCAST_ROLES));

// --- Contact Lists ---

// GET /api/sms/contacts — list all contact lists
router.get('/', async (req, res, next) => {
  try {
    const page = Math.max(1, Number(req.query.page) || 1);
    const limit = Math.min(100, Math.max(1, Number(req.query.limit) || 50));
    const result = await smsContactsService.findAll(page, limit);
    res.json(result);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts — create a new contact list
router.post('/', validate(createContactListSchema), async (req, res, next) => {
  try {
    const list = await smsContactsService.createList(req.body, req.user!.id);
    res.status(201).json(list);
  } catch (err) { next(err); }
});

// GET /api/sms/contacts/all-entries — list entries across all lists
router.get('/all-entries', async (req, res, next) => {
  try {
    const page = Math.max(1, Number(req.query.page) || 1);
    const limit = Math.min(100, Math.max(1, Number(req.query.limit) || 50));
    const listId = req.query.listId as string | undefined;
    const search = req.query.search as string | undefined;
    const result = await smsContactsService.getAllEntries(page, limit, listId, search);
    res.json(result);
  } catch (err) { next(err); }
});

// --- Database Import Previews (must be BEFORE /:id routes) ---

// GET /api/sms/contacts/preview-users — preview users with phone numbers
router.get('/preview-users', async (req, res, next) => {
  try {
    const result = await smsContactsService.previewUsers({
      role: req.query.role as string | undefined,
    });
    res.json(result);
  } catch (err) { next(err); }
});

// GET /api/sms/contacts/preview-addresses — preview addresses with phone numbers
router.get('/preview-addresses', async (req, res, next) => {
  try {
    const result = await smsContactsService.previewAddresses({
      province: req.query.province as string | undefined,
      supportLevel: req.query.supportLevel as string | undefined,
    });
    res.json(result);
  } catch (err) { next(err); }
});

// GET /api/sms/contacts/preview-signups — preview shift signups with phone numbers
router.get('/preview-signups', async (req, res, next) => {
  try {
    const result = await smsContactsService.previewSignups({
      shiftId: req.query.shiftId as string | undefined,
    });
    res.json(result);
  } catch (err) { next(err); }
});

// GET /api/sms/contacts/preview-conversations — preview conversations
router.get('/preview-conversations', async (req, res, next) => {
  try {
    const result = await smsContactsService.previewConversations({
      campaignId: req.query.campaignId as string | undefined,
      responseType: req.query.responseType as string | undefined,
    });
    res.json(result);
  } catch (err) { next(err); }
});

// GET /api/sms/contacts/preview-contacts — preview CRM contacts with phones
router.get('/preview-contacts', async (req, res, next) => {
  try {
    const result = await smsContactsService.previewContacts({
      tag: req.query.tag as string | undefined,
      supportLevel: req.query.supportLevel as string | undefined,
    });
    res.json(result);
  } catch (err) { next(err); }
});

// --- Single List Routes (/:id) ---

// GET /api/sms/contacts/:id — get a single contact list
router.get('/:id', async (req, res, next) => {
  try {
    const list = await smsContactsService.findById(req.params.id as string);
    if (!list) { res.status(404).json({ error: 'Contact list not found' }); return; }
    res.json(list);
  } catch (err) { next(err); }
});

// PUT /api/sms/contacts/:id — update a contact list
router.put('/:id', validate(updateContactListSchema), async (req, res, next) => {
  try {
    const list = await smsContactsService.updateList(req.params.id as string, req.body);
    res.json(list);
  } catch (err) { next(err); }
});

// DELETE /api/sms/contacts/:id — archive a contact list
router.delete('/:id', async (req, res, next) => {
  try {
    await smsContactsService.archiveList(req.params.id as string);
    res.json({ success: true });
  } catch (err) { next(err); }
});

// --- Entries ---

// GET /api/sms/contacts/:id/entries — list entries in a contact list
router.get('/:id/entries', async (req, res, next) => {
  try {
    const page = Math.max(1, Number(req.query.page) || 1);
    const limit = Math.min(500, Math.max(1, Number(req.query.limit) || 100));
    const result = await smsContactsService.getEntries(req.params.id as string, page, limit);
    res.json(result);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts/:id/entries — add a single entry
router.post('/:id/entries', validate(createContactEntrySchema), async (req, res, next) => {
  try {
    const entry = await smsContactsService.addEntry(req.params.id as string, req.body);
    res.status(201).json(entry);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts/:id/entries/bulk — add multiple entries at once
router.post('/:id/entries/bulk', validate(bulkAddEntriesSchema), async (req, res, next) => {
  try {
    const result = await smsContactsService.addEntriesBulk(req.params.id as string, req.body.entries);
    res.json(result);
  } catch (err) { next(err); }
});

// DELETE /api/sms/contacts/:id/entries/:entryId — remove an entry
router.delete('/:id/entries/:entryId', async (req, res, next) => {
  try {
    await smsContactsService.deleteEntry(req.params.entryId as string);
    res.json({ success: true });
  } catch (err) { next(err); }
});

// --- Import ---

// POST /api/sms/contacts/:id/import-csv — import contacts from CSV text
router.post('/:id/import-csv', async (req, res, next) => {
  try {
    const { csv, filename } = req.body as { csv?: string; filename?: string };
    if (!csv || typeof csv !== 'string') {
      res.status(400).json({ error: 'CSV text is required in the "csv" field' });
      return;
    }
    const MAX_CSV_SIZE = 5 * 1024 * 1024; // 5MB
    if (csv.length > MAX_CSV_SIZE) {
      res.status(400).json({ error: { message: 'CSV too large (max 5MB)', code: 'CSV_TOO_LARGE' } });
      return;
    }
    const result = await smsContactsService.importCsv(req.params.id as string, csv, filename);
    res.json(result);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts/:id/import-phone — import contacts from phone address book
router.post('/:id/import-phone', async (req, res, next) => {
  try {
    const result = await smsContactsService.importFromPhone(req.params.id as string);
    res.json(result);
  } catch (err) { next(err); }
});

// --- Database Import Routes ---

// POST /api/sms/contacts/:id/import-users — import users with phone numbers
router.post('/:id/import-users', async (req, res, next) => {
  try {
    const { role } = req.body as { role?: string };
    const result = await smsContactsService.importFromUsers(req.params.id as string, { role });
    res.json(result);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts/:id/import-addresses — import addresses with phone numbers
router.post('/:id/import-addresses', async (req, res, next) => {
  try {
    const { province, supportLevel } = req.body as { province?: string; supportLevel?: string };
    const result = await smsContactsService.importFromAddresses(req.params.id as string, { province, supportLevel });
    res.json(result);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts/:id/import-signups — import shift signups with phone numbers
router.post('/:id/import-signups', async (req, res, next) => {
  try {
    const { shiftId } = req.body as { shiftId?: string };
    const result = await smsContactsService.importFromSignups(req.params.id as string, { shiftId });
    res.json(result);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts/:id/import-conversations — import from conversations
router.post('/:id/import-conversations', async (req, res, next) => {
  try {
    const { campaignId, responseType } = req.body as { campaignId?: string; responseType?: string };
    const result = await smsContactsService.importFromConversations(req.params.id as string, { campaignId, responseType });
    res.json(result);
  } catch (err) { next(err); }
});

// POST /api/sms/contacts/:id/import-contacts — import CRM contacts with phones
router.post('/:id/import-contacts', async (req, res, next) => {
  try {
    const { tag, supportLevel } = req.body as { tag?: string; supportLevel?: string };
    const result = await smsContactsService.importFromContacts(req.params.id as string, { tag, supportLevel });
    res.json(result);
  } catch (err) { next(err); }
});

export const smsContactsRouter = router;
