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

type Params = {
  params: Promise<{ id: 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'
  };
}

function canViewCommercialData(membership: { role: string; permissions?: string[] | null }) {
  return (
    membership.role === 'admin' ||
    (membership.permissions ?? []).includes(PERMISSIONS.crmQuotationPricingRead)
  );
}

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

    if (!canViewCommercialData(membership)) {
      return NextResponse.json({ message: 'Forbidden' }, { status: 403 });
    }

    const items = await listOpportunityAttachments(
      id,
      organization.id,
      buildAccessContext({
        organizationId: organization.id,
        userId: session.user.id,
        membership
      })
    );

    return NextResponse.json({
      success: true,
      time: new Date().toISOString(),
      message: 'Opportunity purchase order attachments loaded successfully',
      items
    });
  } 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 attachments' }, { status: 500 });
  }
}

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

    if (!canViewCommercialData(membership)) {
      return NextResponse.json({ message: 'Forbidden' }, { status: 403 });
    }

    const formData = await request.formData();
    const file = formData.get('file');

    if (!(file instanceof File)) {
      return NextResponse.json({ message: 'PO attachment file is required' }, { status: 400 });
    }

    const created = await uploadPurchaseOrderAttachment({
      opportunityId: id,
      organizationId: organization.id,
      userId: session.user.id,
      description:
        typeof formData.get('description') === 'string' ? (formData.get('description') as string) : null,
      file: {
        name: file.name,
        type: file.type,
        size: file.size,
        buffer: Buffer.from(await file.arrayBuffer())
      },
      accessContext: buildAccessContext({
        organizationId: organization.id,
        userId: session.user.id,
        membership
      })
    });

    return NextResponse.json({
      success: true,
      message: 'PO attachment uploaded successfully',
      attachment: created
    });
  } 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 upload PO attachment' }, { status: 500 });
  }
}

