import { eq } from 'drizzle-orm';
import { NextRequest, NextResponse } from 'next/server';
import { trainingPolicies } from '@/db/schema';
import {
  AUDIT_ACTION,
  AUDIT_MODULE,
  getRequestMetadata,
  logAuditEvent,
  toAuditValue
} from '@/features/audit-logs/server/audit-service';
import type {
  TrainingPolicyFilters,
  TrainingPolicyMutationPayload
} from '@/features/training-policy/api/types';
import {
  getTrainingPolicyByYearForOrganization,
  listTrainingPoliciesForOrganization,
  normalizeTrainingPolicyPayload,
  serializeTrainingPolicy
} from '@/features/training-policy/server/training-policy-data';
import { AuthError, requirePermission } from '@/lib/auth/session';
import { db } from '@/lib/db';

function readFilters(request: NextRequest): TrainingPolicyFilters {
  const { searchParams } = request.nextUrl;

  return {
    page: Number(searchParams.get('page') ?? 1),
    limit: Number(searchParams.get('limit') ?? 10),
    search: searchParams.get('search') ?? undefined,
    status: searchParams.get('status') ?? undefined,
    sort: searchParams.get('sort') ?? undefined
  };
}

export async function GET(request: NextRequest) {
  try {
    const { organization } = await requirePermission('training_policy:read');
    const filters = readFilters(request);
    const result = await listTrainingPoliciesForOrganization({
      organizationId: organization.id,
      filters
    });

    return NextResponse.json({
      success: true,
      time: new Date().toISOString(),
      message: 'โหลดนโยบายการอบรมเรียบร้อยแล้ว',
      total_training_policies: result.total,
      offset: result.offset,
      limit: result.limit,
      active_policy: result.activePolicy,
      policies: result.policies
    });
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

    console.error('GET /api/training-policies failed', error);
    return NextResponse.json({ message: 'ไม่สามารถโหลดนโยบายการอบรมได้' }, { status: 500 });
  }
}

export async function POST(request: NextRequest) {
  try {
    const { organization, session } = await requirePermission('training_policy:write');
    const requestMetadata = getRequestMetadata(request);
    const body = normalizeTrainingPolicyPayload(
      (await request.json()) as TrainingPolicyMutationPayload
    );

    const existingPolicy = await getTrainingPolicyByYearForOrganization({
      year: body.year,
      organizationId: organization.id
    });

    if (existingPolicy) {
      return NextResponse.json(
        {
          success: false,
          message: `มีนโยบายการอบรมสำหรับปี ${body.year} อยู่แล้ว`
        },
        { status: 409 }
      );
    }

    const policy = await db.transaction(async (tx) => {
      if (body.isActive) {
        await tx
          .update(trainingPolicies)
          .set({ isActive: false, updatedAt: new Date() })
          .where(eq(trainingPolicies.organizationId, organization.id));
      }

      const [createdPolicy] = await tx
        .insert(trainingPolicies)
        .values({
          organizationId: organization.id,
          year: body.year,
          totalHours: body.totalHours,
          kHours: body.kHours,
          sHours: body.sHours,
          aHours: body.aHours,
          isActive: body.isActive
        })
        .returning();

      return createdPolicy;
    });

    const serializedPolicy = serializeTrainingPolicy(policy, {
      updatedByName: session.user.name ?? null
    });

    await logAuditEvent({
      organizationId: organization.id,
      userId: session.user.id,
      module: AUDIT_MODULE.TRAINING_POLICY,
      action: AUDIT_ACTION.CREATE,
      entityName: `ปี ${policy.year}`,
      entityId: policy.id,
      newValue: toAuditValue(serializedPolicy),
      ...requestMetadata
    });

    return NextResponse.json(
      {
        success: true,
        time: new Date().toISOString(),
        message: 'สร้างนโยบายการอบรมเรียบร้อยแล้ว',
        policy: serializedPolicy
      },
      { status: 201 }
    );
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

    console.error('POST /api/training-policies failed', error);
    return NextResponse.json({ message: 'ไม่สามารถสร้างนโยบายการอบรมได้' }, { status: 500 });
  }
}
