import { and, eq } from "drizzle-orm"
import { db } from "@/lib/db"
import { profiles, rent_payments, leases, inspections } from "@/lib/db/schema"

// Public, token-authenticated iCal (ICS) subscription feed. A landlord subscribes
// to /api/calendar/<calendar_token>.ics in Google/Apple/Outlook and their rent
// due dates, lease expiries, and inspections appear (read-only, auto-refreshing).
export const dynamic = "force-dynamic"

const PRODID = "-//Property Management Network//Calendar//EN"

function icsDate(d: string): string {
  return d.slice(0, 10).replace(/-/g, "")
}
function icsDatePlusOne(d: string): string {
  const dt = new Date(d.slice(0, 10) + "T00:00:00Z")
  dt.setUTCDate(dt.getUTCDate() + 1)
  return dt.toISOString().slice(0, 10).replace(/-/g, "")
}
function esc(s: unknown): string {
  return String(s ?? "").replace(/[\\;,]/g, (m) => "\\" + m).replace(/\r?\n/g, "\\n")
}
// Fold lines to 75 octets per RFC 5545.
function fold(line: string): string {
  if (line.length <= 75) return line
  const parts: string[] = []
  let rest = line
  parts.push(rest.slice(0, 75))
  rest = rest.slice(75)
  while (rest.length > 74) {
    parts.push(" " + rest.slice(0, 74))
    rest = rest.slice(74)
  }
  if (rest.length) parts.push(" " + rest)
  return parts.join("\r\n")
}

export async function GET(_req: Request, { params }: { params: Promise<{ token: string }> }) {
  const { token: raw } = await params
  const token = raw.replace(/\.ics$/i, "")
  if (!token) return new Response("Not found", { status: 404 })

  const profile = await db.query.profiles.findFirst({
    where: eq(profiles.calendar_token, token),
    columns: { id: true },
  })
  if (!profile) return new Response("Not found", { status: 404 })
  const ownerId = profile.id

  const [payments, leaseList, inspList] = await Promise.all([
    db.query.rent_payments.findMany({
      where: eq(rent_payments.user_id, ownerId),
      columns: { id: true, due_date: true, amount: true, status: true },
      with: { tenant: { columns: { first_name: true, last_name: true } }, property: { columns: { name: true } }, unit: { columns: { unit_number: true } } },
    }),
    db.query.leases.findMany({
      where: and(eq(leases.user_id, ownerId), eq(leases.status, "active")),
      columns: { id: true, lease_end: true },
      with: { tenant: { columns: { first_name: true, last_name: true } }, property: { columns: { name: true } } },
    }),
    db.query.inspections.findMany({
      where: eq(inspections.user_id, ownerId),
      columns: { id: true, date: true, type: true, status: true },
      with: { property: { columns: { name: true } }, unit: { columns: { unit_number: true } } },
    }),
  ])

  const stamp = new Date().toISOString().replace(/[-:]/g, "").split(".")[0] + "Z"
  const out: string[] = [
    "BEGIN:VCALENDAR",
    "VERSION:2.0",
    `PRODID:${PRODID}`,
    "CALSCALE:GREGORIAN",
    "METHOD:PUBLISH",
    "X-WR-CALNAME:Property Management Network",
    "X-WR-TIMEZONE:UTC",
    "REFRESH-INTERVAL;VALUE=DURATION:PT6H",
    "X-PUBLISHED-TTL:PT6H",
  ]

  const addEvent = (uid: string, date: string, summary: string, description: string) => {
    out.push(
      "BEGIN:VEVENT",
      fold(`UID:${uid}@propertymanagement.network`),
      `DTSTAMP:${stamp}`,
      `DTSTART;VALUE=DATE:${icsDate(date)}`,
      `DTEND;VALUE=DATE:${icsDatePlusOne(date)}`,
      fold(`SUMMARY:${esc(summary)}`),
      fold(`DESCRIPTION:${esc(description)}`),
      "TRANSP:TRANSPARENT",
      "END:VEVENT"
    )
  }

  for (const p of payments) {
    if (!p.due_date) continue
    const who = `${p.tenant?.first_name ?? ""} ${p.tenant?.last_name ?? ""}`.trim() || "Tenant"
    const amt = `$${Number(p.amount).toLocaleString("en-US")}`
    addEvent(`rent-${p.id}`, p.due_date, `Rent due — ${who} (${amt})`, `${p.status.toUpperCase()} · ${p.property?.name ?? ""}${p.unit ? ` Unit ${p.unit.unit_number}` : ""}`)
  }
  for (const l of leaseList) {
    if (!l.lease_end) continue
    const who = `${l.tenant?.first_name ?? ""} ${l.tenant?.last_name ?? ""}`.trim() || "Tenant"
    addEvent(`lease-${l.id}`, l.lease_end, `Lease ends — ${who}`, `${l.property?.name ?? ""}`)
  }
  for (const ins of inspList) {
    if (!ins.date) continue
    const type = ins.type.replace("_", "-")
    addEvent(`insp-${ins.id}`, ins.date, `${type} inspection`, `${ins.property?.name ?? ""}${ins.unit ? ` Unit ${ins.unit.unit_number}` : ""} · ${ins.status}`)
  }

  out.push("END:VCALENDAR")

  return new Response(out.join("\r\n") + "\r\n", {
    headers: {
      "Content-Type": "text/calendar; charset=utf-8",
      "Content-Disposition": 'inline; filename="property-management-network.ics"',
      "Cache-Control": "public, max-age=3600",
    },
  })
}
