import { Router, Request, Response } from 'express';
import { prisma } from '../index';
import { asyncHandler } from '../middleware/errorHandler';
import { authenticateToken, AuthenticatedRequest } from '../middleware/auth';
import { emailService } from '../services/emailService';
import Joi from 'joi';

const router = Router();

// Helper function to normalize date input to avoid timezone issues
function normalizeDate(dateInput: any): Date {
  if (typeof dateInput === 'string') {
    // If it's a string in YYYY-MM-DD format, create date in local time
    const [year, month, day] = dateInput.split('-');
    return new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
  }
  if (dateInput instanceof Date) {
    // If it's already a Date object, extract date parts and recreate to avoid timezone issues
    const year = dateInput.getFullYear();
    const month = dateInput.getMonth();
    const day = dateInput.getDate();
    return new Date(year, month, day);
  }
  return dateInput;
}

// Validation schemas
const createDocketEntrySchema = Joi.object({
  date: Joi.date().required(),
  title: Joi.string().required().max(500),
  summary: Joi.string().required(),
  notes: Joi.string().optional().allow(''),
});

const updateDocketEntrySchema = Joi.object({
  date: Joi.date().optional(),
  title: Joi.string().optional().max(500),
  summary: Joi.string().optional(),
  notes: Joi.string().optional().allow(''),
});

// Public endpoint - Get all docket entries with documents
router.get('/', asyncHandler(async (req: Request, res: Response) => {
  const entries = await prisma.docketEntry.findMany({
    include: {
      documents: {
        orderBy: {
          displayOrder: 'asc',
        },
      },
    },
    orderBy: {
      date: 'asc',
    },
  });

  res.json({
    success: true,
    entries,
  });
}));

// Admin endpoint - Get single docket entry
router.get('/:id', authenticateToken, asyncHandler(async (req: AuthenticatedRequest, res: Response) => {
  const entryId = parseInt(req.params.id);
  
  if (isNaN(entryId)) {
    return res.status(400).json({
      success: false,
      message: 'Invalid entry ID',
    });
  }

  const entry = await prisma.docketEntry.findUnique({
    where: { id: entryId },
    include: {
      documents: {
        orderBy: {
          displayOrder: 'asc',
        },
      },
    },
  });

  if (!entry) {
    return res.status(404).json({
      success: false,
      message: 'Docket entry not found',
    });
  }

  res.json({
    success: true,
    entry,
  });
}));

// Admin endpoint - Create new docket entry
router.post('/', authenticateToken, asyncHandler(async (req: AuthenticatedRequest, res: Response) => {
  const { error, value } = createDocketEntrySchema.validate(req.body);
  
  if (error) {
    return res.status(400).json({
      success: false,
      message: error.details[0].message,
    });
  }

  // Normalize date to avoid timezone issues
  const normalizedData = { ...value };
  if (value.date) {
    normalizedData.date = normalizeDate(value.date);
  }

  const entry = await prisma.docketEntry.create({
    data: normalizedData,
    include: {
      documents: {
        orderBy: {
          displayOrder: 'asc',
        },
      },
    },
  });

  // Email notifications are now manual-only via the green mail button
  // Automatic notifications disabled per user request

  res.status(201).json({
    success: true,
    message: 'Docket entry created successfully',
    entry,
  });
}));

// Admin endpoint - Update docket entry
router.put('/:id', authenticateToken, asyncHandler(async (req: AuthenticatedRequest, res: Response) => {
  const entryId = parseInt(req.params.id);
  
  if (isNaN(entryId)) {
    return res.status(400).json({
      success: false,
      message: 'Invalid entry ID',
    });
  }

  const { error, value } = updateDocketEntrySchema.validate(req.body);
  
  if (error) {
    return res.status(400).json({
      success: false,
      message: error.details[0].message,
    });
  }

  // Normalize date to avoid timezone issues
  const normalizedData = { ...value };
  if (value.date) {
    normalizedData.date = normalizeDate(value.date);
  }

  try {
    const entry = await prisma.docketEntry.update({
      where: { id: entryId },
      data: normalizedData,
      include: {
        documents: {
          orderBy: {
            displayOrder: 'asc',
          },
        },
      },
    });

    res.json({
      success: true,
      message: 'Docket entry updated successfully',
      entry,
    });
  } catch (error: any) {
    if (error.code === 'P2025') {
      return res.status(404).json({
        success: false,
        message: 'Docket entry not found',
      });
    }
    throw error;
  }
}));

// Admin endpoint - Delete docket entry
router.delete('/:id', authenticateToken, asyncHandler(async (req: AuthenticatedRequest, res: Response) => {
  const entryId = parseInt(req.params.id);
  
  if (isNaN(entryId)) {
    return res.status(400).json({
      success: false,
      message: 'Invalid entry ID',
    });
  }

  try {
    // Delete associated documents first (cascade should handle this, but being explicit)
    await prisma.document.deleteMany({
      where: { docketEntryId: entryId },
    });

    // Delete the docket entry
    await prisma.docketEntry.delete({
      where: { id: entryId },
    });

    res.json({
      success: true,
      message: 'Docket entry deleted successfully',
    });
  } catch (error: any) {
    if (error.code === 'P2025') {
      return res.status(404).json({
        success: false,
        message: 'Docket entry not found',
      });
    }
    throw error;
  }
}));

export default router;
