/**
 * /v1/time routes — zapier-make-integration (wave-13).
 * POST /v1/time — log a time entry
 *
 * Auth: scope `time:write`.
 * Tier: Business+ required.
 */
import { z } from 'zod'
import { timeEntries, projects } from '@zync/db'
import { eq, and } from 'drizzle-orm'
import { serializeTimeEntry, hasScope, errForbiddenScope } from '../index'
import type { PublicApiContext } from '../app'

const createTimeEntrySchema = z.object({
  project_id: z.string().uuid(),
  task_id: z.string().uuid().optional(),
  description: z.string().optional(),
  date: z.string().optional(), // ISO date yyyy-mm-dd; defaults to today
  duration_minutes: z.number().int().positive(),
})

/** POST /v1/time */
export async function createTimeEntry(ctx: PublicApiContext): Promise<Response> {
  if (!hasScope(ctx.scopes, 'time:write')) return errForbiddenScope('time:write')
  const { db, tenantId, userId } = ctx

  let body: unknown
  try {
    body = await ctx.request.json()
  } catch {
    return new Response(JSON.stringify({ error: 'validation_error', message: 'Invalid JSON body' }), {
      status: 422, headers: { 'Content-Type': 'application/json' },
    })
  }

  const parsed = createTimeEntrySchema.safeParse(body)
  if (!parsed.success) {
    return new Response(
      JSON.stringify({
        error: 'validation_error',
        message: parsed.error.issues[0]?.message ?? 'Invalid input',
        field: parsed.error.issues[0]?.path.join('.'),
      }),
      { status: 422, headers: { 'Content-Type': 'application/json' } },
    )
  }

  const data = parsed.data

  // Validate project belongs to tenant
  const [project] = await db
    .select({ id: projects.id })
    .from(projects)
    .where(and(eq(projects.id, data.project_id), eq(projects.tenantId, tenantId)))
    .limit(1)

  if (!project) {
    return new Response(JSON.stringify({ error: 'not_found', message: 'Project not found' }), {
      status: 404, headers: { 'Content-Type': 'application/json' },
    })
  }

  const durationSeconds = data.duration_minutes * 60

  // Compute startedAt from date or now
  let startedAt: Date
  if (data.date) {
    startedAt = new Date(`${data.date}T00:00:00Z`)
  } else {
    startedAt = new Date()
  }
  const stoppedAt = new Date(startedAt.getTime() + durationSeconds * 1000)

  const [inserted] = await db
    .insert(timeEntries)
    .values({
      tenantId,
      userId: userId ?? null,
      projectId: data.project_id,
      taskId: data.task_id ?? null,
      description: data.description ?? null,
      startedAt,
      stoppedAt,
      durationSeconds,
      source: 'manual',
      billable: true,
      approvalStatus: 'auto_approved',
    })
    .returning()

  if (!inserted) {
    return new Response(JSON.stringify({ error: 'internal_error', message: 'Failed to create time entry' }), {
      status: 500, headers: { 'Content-Type': 'application/json' },
    })
  }

  return new Response(
    JSON.stringify(serializeTimeEntry({
      id: inserted.id,
      projectId: inserted.projectId,
      taskId: inserted.taskId,
      description: inserted.description,
      startedAt: inserted.startedAt,
      stoppedAt: inserted.stoppedAt,
      durationSeconds: inserted.durationSeconds,
      billable: inserted.billable,
      source: inserted.source,
      createdAt: inserted.createdAt,
    })),
    { status: 201, headers: { 'Content-Type': 'application/json' } },
  )
}
