import { NextRequest, NextResponse } from 'next/server';
import { getOpportunityAttachment } from '@/features/crm/opportunities/server/service';
import { getStorageProvider } from '@/features/foundation/storage/service';
import { PERMISSIONS } from '@/lib/auth/rbac';
import { AuthError, requireOrganizationAccess } from '@/lib/auth/session';

type Params = {
  params: Promise<{ id: string; attachmentId: string }>;
};

function buildAccessContext(input: {
  organizationId: string;
  userId: string;
  membership: {
    role: string;
    businessRole: string;
    permissions?: string[] | null;
    branchScopeIds?: string[] | null;
    productTypeScopeIds?: string[] | null;
    ownershipScope?: string | null;
    branchScopeMode?: string | null;
    productScopeMode?: string | null;
  };
}) {
  return {
    organizationId: input.organizationId,
    userId: input.userId,
    membershipRole: input.membership.role,
    businessRole: input.membership.businessRole,
    permissions: input.membership.permissions ?? [],
    branchScopeIds: input.membership.branchScopeIds ?? [],
    productTypeScopeIds: input.membership.productTypeScopeIds ?? [],
    ownershipScope: input.membership.ownershipScope ?? 'organization',
    branchScopeMode: input.membership.branchScopeMode === 'assigned' ? 'assigned' : 'all',
    productScopeMode: input.membership.productScopeMode === 'assigned' ? 'assigned' : 'all'
  };
}

export async function GET(request: NextRequest, { params }: Params) {
  try {
    const { id, attachmentId } = await params;
    const { organization, session, membership } = await requireOrganizationAccess({
      permission: PERMISSIONS.crmOpportunityRead
    });

    if (
      membership.role !== 'admin' &&
      !(membership.permissions ?? []).includes(PERMISSIONS.crmQuotationPricingRead)
    ) {
      return NextResponse.json({ message: 'Forbidden' }, { status: 403 });
    }

    const attachment = await getOpportunityAttachment(
      id,
      attachmentId,
      organization.id,
      buildAccessContext({
        organizationId: organization.id,
        userId: session.user.id,
        membership
      })
    );
    const object = await getStorageProvider().getObject({ key: attachment.storageKey });
    const download = request.nextUrl.searchParams.get('download') === '1';

    return new NextResponse(object.body, {
      headers: {
        'Content-Type': attachment.fileType ?? object.contentType,
        'Content-Disposition': `${download ? 'attachment' : 'inline'}; filename="${attachment.originalFileName}"`
      }
    });
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

    if (error instanceof Error) {
      return NextResponse.json({ message: error.message }, { status: 400 });
    }

    return NextResponse.json({ message: 'Unable to load PO attachment' }, { status: 500 });
  }
}

