import { NextRequest, NextResponse } from 'next/server';
import { trainingMatrices } from '@/db/schema';
import type { TrainingMatrixMutationPayload } from '@/features/training-matrix/api/types';
import {
  canManageTrainingMatrix,
  listTrainingMatricesForOrganization,
  normalizeTrainingMatrixPayload,
  serializeTrainingMatrix
} from '@/features/training-matrix/server/training-matrix-data';
import { AuthError, requireOrganizationAccess } from '@/lib/auth/session';
import { db } from '@/lib/db';

export async function GET(request: NextRequest) {
  try {
    const { organization, membership } = await requireOrganizationAccess();

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

    const { searchParams } = request.nextUrl;
    const result = await listTrainingMatricesForOrganization({
      organizationId: organization.id,
      filters: {
        page: Number(searchParams.get('page') ?? 1),
        limit: Number(searchParams.get('limit') ?? 10),
        search: searchParams.get('search') ?? undefined,
        sort: searchParams.get('sort') ?? undefined
      }
    });

    return NextResponse.json({
      success: true,
      time: new Date().toISOString(),
      message: 'Training matrix loaded successfully',
      total_training_matrices: result.total,
      offset: result.offset,
      limit: result.limit,
      training_matrices: result.matrices
    });
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

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

export async function POST(request: NextRequest) {
  try {
    const { organization, membership } = await requireOrganizationAccess();

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

    const body = normalizeTrainingMatrixPayload(
      (await request.json()) as TrainingMatrixMutationPayload
    );

    const [matrix] = await db
      .insert(trainingMatrices)
      .values({
        organizationId: organization.id,
        departmentId: body.departmentId,
        positionId: body.positionId,
        courseId: body.courseId,
        isRequired: body.isRequired,
        renewalPeriodMonths: body.renewalPeriodMonths,
        note: body.note
      })
      .returning();

    const fullMatrix = await listTrainingMatricesForOrganization({
      organizationId: organization.id,
      filters: { page: 1, limit: 1, search: String(matrix.id) }
    });

    return NextResponse.json(
      {
        success: true,
        time: new Date().toISOString(),
        message: 'Training matrix created successfully',
        training_matrix:
          fullMatrix.matrices.find((item) => item.id === matrix.id) ??
          serializeTrainingMatrix({
            id: matrix.id,
            organizationId: matrix.organizationId,
            departmentId: matrix.departmentId,
            departmentName: null,
            positionId: matrix.positionId,
            positionName: null,
            courseId: matrix.courseId,
            courseName: '',
            courseCategory: '',
            courseCertificateValidityMonths: null,
            isRequired: matrix.isRequired,
            renewalPeriodMonths: matrix.renewalPeriodMonths,
            note: matrix.note,
            createdAt: matrix.createdAt,
            updatedAt: matrix.updatedAt
          })
      },
      { status: 201 }
    );
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

    return NextResponse.json({ message: 'Unable to create training matrix' }, { status: 500 });
  }
}
