/**
 * POST /api/analyzer/analyses/:id/share
 *
 * Body: { recipientEmail: string, note?: string }
 *
 * Records a share row in analyzer_shares (audit log) and emails the recipient
 * a link to the analysis. The audit row is persisted FIRST; if the email
 * send fails the response carries `emailSent: false` + the error message,
 * but the share row stays. This matches the spec's "share is an audit log"
 * framing — we'd rather record an attempted share than lose it.
 */

import { NextRequest, NextResponse } from 'next/server';
import { requireAuth } from '@/lib/auth-utils';
import { ShareAnalysisRequest } from '@/lib/types/analyzer';
import {
  createShare,
  getAnalysisById,
} from '@/lib/services/analyzer/persistence';
import postgresClient from '@/lib/services/postgres-client';
import { sendAnalysisShareEmail } from '@/lib/services/email';

function getAllowedDomains(): string[] {
  const raw = process.env.ALLOWED_SHARE_DOMAINS ?? '';
  return raw
    .split(',')
    .map((d) => d.trim().toLowerCase())
    .filter((d) => d.length > 0);
}

function getAppBaseUrl(): string {
  return (
    process.env.BETTER_AUTH_URL ||
    process.env.NEXT_PUBLIC_BETTER_AUTH_URL ||
    'http://localhost:3100'
  );
}

export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { session, error } = await requireAuth();
  if (error) return error;

  const { id } = await params;

  const body = await request.json().catch(() => ({}));
  const result = ShareAnalysisRequest.safeParse(body);
  if (!result.success) {
    return NextResponse.json(
      { error: 'Invalid request body', details: result.error.issues },
      { status: 400 }
    );
  }
  const { recipientEmail, note } = result.data;

  const allowedDomains = getAllowedDomains();
  if (allowedDomains.length === 0) {
    return NextResponse.json(
      {
        error: 'Sharing is not configured',
        message: 'ALLOWED_SHARE_DOMAINS env var is empty.',
      },
      { status: 503 }
    );
  }
  const domain = recipientEmail.split('@')[1]?.toLowerCase();
  if (!domain || !allowedDomains.includes(domain)) {
    return NextResponse.json(
      {
        error: 'Recipient domain is not allowed',
        message: `Allowed domains: ${allowedDomains.join(', ')}`,
      },
      { status: 403 }
    );
  }

  const analysis = await getAnalysisById(id);
  if (!analysis) {
    return NextResponse.json({ error: 'Analysis not found' }, { status: 404 });
  }

  const sessionUser = session?.user as {
    id: string;
    email: string;
    name?: string;
  };
  const share = await createShare({
    analysis_id: id,
    shared_by_user_id: sessionUser.id,
    shared_with_email: recipientEmail,
    note,
  });

  // Fetch the ticket title for the email subtitle. Best-effort: a missing
  // ticket (analyzer mirror skew) shouldn't fail the share.
  let ticketTitle: string | null = null;
  try {
    const titleRes = await postgresClient.query<{ title: string | null }>(
      `SELECT title FROM tickets
        WHERE ticket_number = $1
          AND COALESCE(is_deleted, false) = false
        LIMIT 1`,
      [analysis.ticketNumber]
    );
    if (titleRes.rowCount && titleRes.rowCount > 0) {
      ticketTitle = titleRes.rows[0].title;
    }
  } catch {
    // Title is decorative — proceed without it.
  }

  const modelTier: 'haiku' | 'sonnet' | 'opus' | null = analysis.opusUsed
    ? 'opus'
    : analysis.sonnetUsed
      ? 'sonnet'
      : analysis.haikuUsed
        ? 'haiku'
        : null;

  const analysisUrl = `${getAppBaseUrl().replace(/\/$/, '')}/analyzer/analysis/${id}`;
  let emailSent = true;
  let emailError: string | null = null;
  try {
    await sendAnalysisShareEmail({
      recipientEmail,
      senderName: sessionUser.name || sessionUser.email,
      senderEmail: sessionUser.email,
      ticketNumber: analysis.ticketNumber,
      ticketTitle,
      analysisVersion: analysis.analysisVersion,
      summary: analysis.summary,
      nextStep: analysis.nextStep,
      nextStepRationale: analysis.nextStepRationale,
      whatWasDone: analysis.whatWasDone,
      whatShouldHaveBeenDone: analysis.whatShouldHaveBeenDone,
      gaps: analysis.gaps,
      confidenceScore: analysis.confidenceScore,
      modelTier,
      analysisUrl,
      note,
    });
  } catch (err) {
    emailSent = false;
    emailError = err instanceof Error ? err.message : 'Unknown email error';
    console.error(
      `[ANALYZER-SHARE] email send failed for share ${share.id}:`,
      err
    );
  }

  return NextResponse.json({
    share: {
      id: share.id,
      analysisId: id,
      sharedWithEmail: recipientEmail,
      sharedAt: share.shared_at,
      note: note ?? null,
    },
    emailSent,
    emailError,
  });
}
