import { Router } from "express";
import { z } from "zod";
import { requireAdmin, requireAuth } from "../auth/middleware";
import {
  addEmployee,
  deactivateEmployee,
  findEmployeeById,
  listEmployees,
} from "../services/employees";
import { eventsInRange, summarize } from "../services/attendance";
import { parseRange } from "../util/dateRange";
import { sessionsToCsv } from "../util/csv";

export const adminRouter = Router();
adminRouter.use(requireAuth, requireAdmin);

adminRouter.get("/employees", (_req, res) => {
  res.json({ employees: listEmployees() });
});

const addEmployeeSchema = z.object({
  email: z.string().email(),
  name: z.string().trim().min(1).optional(),
});

adminRouter.post("/employees", (req, res) => {
  const parsed = addEmployeeSchema.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ error: "Valid email is required" });
    return;
  }
  const employee = addEmployee(parsed.data.email, parsed.data.name ?? null);
  res.status(201).json({ employee });
});

adminRouter.delete("/employees/:id", (req, res) => {
  const id = Number(req.params.id);
  if (!Number.isInteger(id)) {
    res.status(400).json({ error: "Invalid employee id" });
    return;
  }
  const removed = deactivateEmployee(id);
  if (!removed) {
    res.status(404).json({ error: "Employee not found" });
    return;
  }
  res.status(204).end();
});

adminRouter.get("/stats", (req, res) => {
  const { fromIso, toIso } = parseRange(req.query as Record<string, unknown>);
  const now = new Date();
  const employees = listEmployees();

  const perEmployee = employees.map((employee) => {
    const events = eventsInRange(employee.id, fromIso, toIso);
    const stats = summarize(events, now);
    return {
      employee,
      totalWorkedMs: stats.totalWorkedMs,
      totalBreakMs: stats.totalBreakMs,
      shiftCount: stats.shiftCount,
    };
  });

  const totals = perEmployee.reduce(
    (acc, e) => ({
      totalWorkedMs: acc.totalWorkedMs + e.totalWorkedMs,
      totalBreakMs: acc.totalBreakMs + e.totalBreakMs,
      shiftCount: acc.shiftCount + e.shiftCount,
    }),
    { totalWorkedMs: 0, totalBreakMs: 0, shiftCount: 0 }
  );

  res.json({ range: { from: fromIso, to: toIso }, totals, employees: perEmployee });
});

adminRouter.get("/stats/:id", (req, res) => {
  const id = Number(req.params.id);
  const employee = Number.isInteger(id) ? findEmployeeById(id) : undefined;
  if (!employee) {
    res.status(404).json({ error: "Employee not found" });
    return;
  }
  const { fromIso, toIso } = parseRange(req.query as Record<string, unknown>);
  const events = eventsInRange(employee.id, fromIso, toIso);
  const stats = summarize(events, new Date());
  res.json({ employee, range: { from: fromIso, to: toIso }, ...stats });
});

adminRouter.get("/stats/:id/export", (req, res) => {
  const id = Number(req.params.id);
  const employee = Number.isInteger(id) ? findEmployeeById(id) : undefined;
  if (!employee) {
    res.status(404).json({ error: "Employee not found" });
    return;
  }
  const { fromIso, toIso } = parseRange(req.query as Record<string, unknown>);
  const events = eventsInRange(employee.id, fromIso, toIso);
  const { sessions } = summarize(events, new Date());
  const csv = sessionsToCsv(sessions);

  const period = fromIso.slice(0, 7);
  const safeName = employee.email.replace(/[^a-z0-9.@-]/gi, "_");

  res.setHeader("Content-Type", "text/csv; charset=utf-8");
  res.setHeader("Content-Disposition", `attachment; filename="${safeName}_${period}.csv"`);
  res.send("﻿" + csv); // BOM so Excel opens the Czech diacritics as UTF-8
});
