import { Hono } from 'hono'
import { z } from 'zod'
import {
  assertTenantOwnsProject,
  createDb,
  getTaskSyncSettings,
  invalidTenantReferenceBody,
  upsertTaskSyncSettings,
} from '@zync/db/queries'
import type { AppEnv } from '../../types'
import { requirePermission } from '../../middleware/guards'
import { runTaskSync } from '../cron/tasks-sync'

const inboundSourcesSchema = z.object({
  email: z.boolean().optional(),
  telegram: z.boolean().optional(),
  slack: z.boolean().optional(),
  whatsapp: z.boolean().optional(),
})

const updateTaskSyncSettingsSchema = z.object({
  sync_interval_minutes: z.number().int().min(15).max(1440).optional(),
  auto_create_tickets_from: inboundSourcesSchema.optional(),
  default_project_id: z.string().uuid().nullable().optional(),
})

export const taskSettingsRoute = new Hono<AppEnv>()

taskSettingsRoute.get('/settings/sync', requirePermission('tasks:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const row = await getTaskSyncSettings(c.get('db'), session.tid)
  return c.json(
    {
      sync_interval_minutes: row?.syncIntervalMinutes ?? 120,
      auto_create_tickets_from: row?.autoCreateTicketsFrom ?? {},
      default_project_id: row?.defaultProjectId ?? null,
    },
    200,
  )
})

taskSettingsRoute.patch('/settings/sync', requirePermission('tasks:write'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const body = await c.req.json().catch(() => null)
  const parsed = updateTaskSyncSettingsSchema.safeParse(body)
  if (!parsed.success) {
    return c.json({ error: 'Invalid request', issues: parsed.error.issues }, 422)
  }

  if (parsed.data.default_project_id !== undefined) {
    if (!(await assertTenantOwnsProject(c.get('db'), session.tid, parsed.data.default_project_id))) {
      return c.json(invalidTenantReferenceBody('default_project_id'), 400)
    }
  }

  const row = await upsertTaskSyncSettings(c.get('db'), session.tid, {
    syncIntervalMinutes: parsed.data.sync_interval_minutes,
    autoCreateTicketsFrom: parsed.data.auto_create_tickets_from,
    defaultProjectId: parsed.data.default_project_id,
  })

  return c.json(
    {
      sync_interval_minutes: row.syncIntervalMinutes,
      auto_create_tickets_from: row.autoCreateTicketsFrom,
      default_project_id: row.defaultProjectId,
    },
    200,
  )
})

taskSettingsRoute.post('/settings/sync/run', requirePermission('tasks:write'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const db = c.get('db') ?? createDb(c.env)
  const results = await runTaskSync({
    db,
    env: c.env,
    tenantIds: [session.tid],
    force: true,
  })

  return c.json({ ok: true, results }, 200)
})
