import { z } from "zod";
import { zValidator } from "@hono/zod-validator";
import { Hono } from "hono";
import { authMiddleware, requireAuth, type AuthVariables } from "../middleware/auth.middleware";
import { tenantMiddleware, requireHousehold, type TenantVariables } from "../middleware/tenant.middleware";
import {
  getMonthStatus,
  closeMonth,
  reopenMonth,
} from "../services/month-status.service";
import { getSettlementV2 } from "../services/fixed-costs.service";

type Variables = AuthVariables & TenantVariables;

const CloseMonthSchema = z.object({
  finalAmount: z.number().min(0),
  toUserId: z.string().min(1),
  notes: z.string().optional(),
});

export const monthsRoutes = new Hono<{ Variables: Variables }>();
monthsRoutes.use("/*", authMiddleware, requireAuth, tenantMiddleware, requireHousehold);

// GET /api/months/:month/status
monthsRoutes.get("/:month/status", async (c) => {
  const householdId = c.get("householdId") as string;
  const { month } = c.req.param();
  const status = await getMonthStatus(householdId, month);
  return c.json({ status });
});

// POST /api/months/:month/close
monthsRoutes.post("/:month/close", zValidator("json", CloseMonthSchema), async (c) => {
  const householdId = c.get("householdId") as string;
  const user = c.get("user") as { id: string };
  const { month } = c.req.param();
  const input = c.req.valid("json");

  try {
    const status = await closeMonth(householdId, month, user.id, input);
    return c.json({ status }, 201);
  } catch (err) {
    const message = err instanceof Error ? err.message : "Fehler beim Abschließen";
    return c.json({ error: message }, 400);
  }
});

// POST /api/months/:month/reopen  (API only — no UI in v1)
monthsRoutes.post("/:month/reopen", async (c) => {
  const householdId = c.get("householdId") as string;
  const { month } = c.req.param();
  const status = await reopenMonth(householdId, month);
  return c.json({ status });
});

// GET /api/months/:month/settlement  — convenience: settlement + status in one call
monthsRoutes.get("/:month/settlement", async (c) => {
  const householdId = c.get("householdId") as string;
  const user = c.get("user") as { id: string };
  const { month } = c.req.param();
  const [status, settlement] = await Promise.all([
    getMonthStatus(householdId, month),
    getSettlementV2(householdId, user.id, month),
  ]);
  return c.json({ status, settlement });
});
