import { NextRequest, NextResponse } from 'next/server';
import { verifySession } from '@/lib/auth';
import { hasEmployeePermission } from '@/lib/employee-permissions';
import { pgGetEmployees, pgGetSettings } from '@/lib/postgres/data-access';
import { pgGetMonthlyAttendanceSummary } from '@/lib/postgres/attendance';

function canAccess(user: any, settings: Record<string, unknown>) {
  return (
    hasEmployeePermission(user, settings, 'admin.hr-attendance') ||
    hasEmployeePermission(user, settings, 'admin.employees')
  );
}

function getEmployeeName(employee: any) {
  return (
    employee?.name ||
    employee?.fullName ||
    employee?.employeeName ||
    employee?.arabicName ||
    employee?.id ||
    'Unknown'
  );
}

export async function GET(request: NextRequest) {
  try {
    const session = await verifySession();
    if (!session?.user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const settings = await pgGetSettings();
    if (!canAccess(session.user, settings)) {
      return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
    }

    const url = new URL(request.url);
    const month = Number(url.searchParams.get('month') || new Date().getMonth() + 1);
    const year = Number(url.searchParams.get('year') || new Date().getFullYear());
    const employeeId = url.searchParams.get('employeeId') || undefined;

    if (!Number.isInteger(month) || month < 1 || month > 12) {
      return NextResponse.json({ error: 'Invalid month' }, { status: 400 });
    }

    if (!Number.isInteger(year) || year < 2000 || year > 2100) {
      return NextResponse.json({ error: 'Invalid year' }, { status: 400 });
    }

    const fromDate = `${year}-${String(month).padStart(2, '0')}-01`;
    const toDate = new Date(year, month, 0).toISOString().slice(0, 10);

    const [summaryRows, employeesResult] = await Promise.all([
      pgGetMonthlyAttendanceSummary({
        fromDate,
        toDate,
        employeeId,
      }),
      pgGetEmployees({ page: 1, pageSize: 10000 }),
    ]);

    const summaryByEmployee = new Map(
      summaryRows.map((row: any) => [String(row.employee_id || ''), row])
    );

    const employees = (employeesResult.items || []) as any[];
    const targetEmployees = employeeId
      ? employees.filter((employee) => String(employee?.id || '') === employeeId)
      : employees;

    const reportItems = targetEmployees.map((employee) => {
      const id = String(employee?.id || '');
      const summary = summaryByEmployee.get(id);

      return {
        employeeId: id,
        employeeName: getEmployeeName(employee),
        presentDays: Number(summary?.present_days || 0),
        absentDays: Number(summary?.absent_days || 0),
        lateCount: Number(summary?.late_count || 0),
        sickDays: Number(summary?.sick_days || 0),
        leaveDays: Number(summary?.leave_days || 0),
        totalHours: Math.round(Number(summary?.total_hours || 0) * 100) / 100,
      };
    });

    const totals = reportItems.reduce(
      (acc, item) => {
        acc.presentDays += item.presentDays;
        acc.absentDays += item.absentDays;
        acc.lateCount += item.lateCount;
        acc.sickDays += item.sickDays;
        acc.leaveDays += item.leaveDays;
        acc.totalHours += item.totalHours;
        return acc;
      },
      {
        presentDays: 0,
        absentDays: 0,
        lateCount: 0,
        sickDays: 0,
        leaveDays: 0,
        totalHours: 0,
      }
    );

    return NextResponse.json({
      month,
      year,
      fromDate,
      toDate,
      items: reportItems,
      totals: {
        ...totals,
        totalHours: Math.round(totals.totalHours * 100) / 100,
      },
    });
  } catch (error) {
    console.error('Error building monthly attendance report:', error);
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
  }
}
