import { NextRequestWithAuth, withAuth } from "next-auth/middleware";
import { ability, authOptions } from "@/config/authConfig";
import { NextFetchEvent, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";

// user groups
export const [
  SUPER_ADMIN,
  TOP_MANAGEMENT,
  TEAM_LEAD,
  NORMAL_STAFF,
  SUPPORTING_STAFF
] = [
    "Super Admin",
    "Top Management",
    "Team Leader",
    "Normal Staff",
    "Supporting Staff"
  ]

// abilities
export const [
  MAINTAIN_USER,
  MAINTAIN_TIMESHEET,
  VIEW_TASK_TEMPLATE,
  VIEW_GROUP,
  VIEW_CLIENT,
  VIEW_SUBSIDIARY,
  VIEW_STAFF,
  VIEW_COMPANY,
  VIEW_SKILL,
  VIEW_DEPARTMENT,
  VIEW_POSITION,
  VIEW_SALARY,
  VIEW_TEAM,
  VIEW_HOLIDAY,
  VIEW_MAIL,
  MAINTAIN_CLIENT,
  MAINTAIN_SUBSIDIARY,
  MAINTAIN_STAFF,
  MAINTAIN_COMPANY,
  MAINTAIN_SKILL,
  MAINTAIN_DEPARTMENT,
  MAINTAIN_POSITION,
  MAINTAIN_SALARY,
  MAINTAIN_TEAM,
  MAINTAIN_GROUP,
  MAINTAIN_HOLIDAY,
  MAINTAIN_MAIL,
  VIEW_DASHBOARD_SELF,
  VIEW_DASHBOARD_ALL,
  IMPORT_INVOICE,
  VIEW_STAFF_PROFILE,
  IMPORT_RECEIPT,
  MAINTAIN_TASK_TEMPLATE,
  MAINTAIN_TIMESHEET_7DAYS,
  VIEW_PROJECT,
  MAINTAIN_PROJECT,
  DELETE_PROJECT,
  MAINTAIN_TIMESHEET_FAST_TIME_ENTRY,
  VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING,
  MAINTAIN_NORMAL_STAFF_WORKSPACE,
  MAINTAIN_MANAGEMENT_STAFF_WORKSPACE,
  GENERATE_LATE_START_REPORT,
  GENERATE_PROJECT_POTENTIAL_DELAY_REPORT,
  GENERATE_RESOURCE_OVERCONSUMPTION_REPORT,
  GENERATE_COST_AND_EXPENSE_REPORT,
  GENERATE_PROJECT_COMPLETION_REPORT,
  GENERATE_PROJECT_PANDL_REPORT,
  GENERATE_FINANCIAL_STATUS_REPORT,
  GENERATE_PROJECT_CASH_FLOW_REPORT,
  GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT,
  GENERATE_CROSS_TEAM_CHARGE_REPORT,
  G_PROJ_MANHOUR_SUMMARY_MONTHLY_REPORT,
  G_PROJ_MANHOUR_SUMMARY_DAILY_REPORT,
  GENERATE_LAST_MODIFIED_REPORT,
  VIEW_ALL_PROJECTS,
  MAINTAIN_ALL_PROJECTS,
  SATURDAY_WORKERS
] = [
    'MAINTAIN_USER',
    'MAINTAIN_TIMESHEET',
    'VIEW_TASK_TEMPLATE',
    'VIEW_GROUP',
    'VIEW_CLIENT',
    'VIEW_SUBSIDIARY',
    'VIEW_STAFF',
    'VIEW_COMPANY',
    'VIEW_SKILL',
    'VIEW_DEPARTMENT',
    'VIEW_POSITION',
    'VIEW_SALARY',
    'VIEW_TEAM',
    'VIEW_HOLIDAY',
    'VIEW_MAIL',
    'MAINTAIN_CLIENT',
    'MAINTAIN_SUBSIDIARY',
    'MAINTAIN_STAFF',
    'MAINTAIN_COMPANY',
    'MAINTAIN_SKILL',
    'MAINTAIN_DEPARTMENT',
    'MAINTAIN_POSITION',
    'MAINTAIN_SALARY',
    'MAINTAIN_TEAM',
    'MAINTAIN_GROUP',
    'MAINTAIN_HOLIDAY',
    'MAINTAIN_MAIL',
    'VIEW_DASHBOARD_SELF',
    'VIEW_DASHBOARD_ALL',
    'IMPORT_INVOICE',
    'VIEW_STAFF_PROFILE',
    'IMPORT_RECEIPT',
    'MAINTAIN_TASK_TEMPLATE',
    'MAINTAIN_TIMESHEET_7DAYS',
    'VIEW_PROJECT',
    'MAINTAIN_PROJECT',
    'DELETE_PROJECT',
    'MAINTAIN_TIMESHEET_FAST_TIME_ENTRY',
    'VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING',
    'MAINTAIN_NORMAL_STAFF_WORKSPACE',
    'MAINTAIN_MANAGEMENT_STAFF_WORKSPACE',
    'G_LATE_START_REPORT',
    'G_PROJECT_POTENTIAL_DELAY_REPORT',
    'G_RESOURCE_OVERCONSUMPTION_REPORT',
    'G_COST_AND_EXPENSE_REPORT',
    'G_PROJECT_COMPLETION_REPORT',
    'G_PROJECT_P&L_REPORT',
    'G_FINANCIAL_STATUS_REPORT',
    'G_PROJECT_CASH_FLOW_REPORT',
    'G_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT',
    'G_CROSS_TEAM_CHARGE_REPORT',
    'G_PROJ_MANHOUR_SUMMARY_MONTHLY_R',
    'G_PROJ_MANHOUR_SUMMARY_DAILY_R',
    'G_LAST_MODIFIED_REPORT',
    'VIEW_ALL_PROJECTS',
    'MAINTAIN_ALL_PROJECTS',
    'SATURDAY_WORKERS'
  ]

const PRIVATE_ROUTES = [
  "/analytics",
  "/dashboard",
  // "/home",
  "/invoice",
  "/projects",
  "/tasks",
  "/settings",
  "/staffReimbursement",
];
const LANG_QUERY_PARAM = "lang";

export default async function middleware(
  req: NextRequestWithAuth,
  event: NextFetchEvent,
) {
  const langPref = req.nextUrl.searchParams.get(LANG_QUERY_PARAM);
  // const token = await getToken({ req: req, secret: process.env.SECRET });
  if (langPref) {
    // Redirect to same url without the lang query param + set cookies
    const newUrl = new URL(req.nextUrl);
    newUrl.searchParams.delete(LANG_QUERY_PARAM);
    const response = NextResponse.redirect(newUrl);
    response.cookies.set("i18next", langPref);
    return response;
  }

  const authMiddleware = withAuth({
    pages: authOptions.pages,
    callbacks: {
      authorized: ({ req, token }) => {
        let isAuth = Boolean(token);
        if (!Boolean(token)) {
          return Boolean(token)
        }
        const abilities = (token!.abilities as ability[]).map((item: ability) => item.actionSubjectCombo);

        if (req.nextUrl.pathname.startsWith('/projects')) {
          isAuth = [MAINTAIN_PROJECT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/tasks')) {
          isAuth = [MAINTAIN_TASK_TEMPLATE].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings')) {
          isAuth = [
            VIEW_CLIENT,
            VIEW_SUBSIDIARY,
            VIEW_STAFF,
            VIEW_COMPANY,
            VIEW_SKILL,
            VIEW_DEPARTMENT,
            VIEW_POSITION,
            VIEW_SALARY,
            VIEW_TEAM,
            VIEW_GROUP,
            VIEW_HOLIDAY,
            VIEW_MAIL,
            MAINTAIN_CLIENT,
            MAINTAIN_SUBSIDIARY,
            MAINTAIN_STAFF,
            MAINTAIN_COMPANY,
            MAINTAIN_SKILL,
            MAINTAIN_DEPARTMENT,
            MAINTAIN_POSITION,
            MAINTAIN_SALARY,
            MAINTAIN_TEAM,
            MAINTAIN_GROUP,
            MAINTAIN_HOLIDAY,
            MAINTAIN_MAIL
          ].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/customer/create') || req.nextUrl.pathname.startsWith('/settings/customer/edit')) {
          isAuth = [MAINTAIN_CLIENT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/subsidiary/create') || req.nextUrl.pathname.startsWith('/settings/subsidiary/edit')) {
          isAuth = [MAINTAIN_SUBSIDIARY].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/staff/create') || req.nextUrl.pathname.startsWith('/settings/staff/edit')) {
          isAuth = [MAINTAIN_STAFF].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/company/create') || req.nextUrl.pathname.startsWith('/settings/company/edit')) {
          isAuth = [MAINTAIN_COMPANY].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/skill/create') || req.nextUrl.pathname.startsWith('/settings/skill/edit')) {
          isAuth = [MAINTAIN_SKILL].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/department/create') || req.nextUrl.pathname.startsWith('/settings/department/edit')) {
          isAuth = [MAINTAIN_DEPARTMENT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/position/create') || req.nextUrl.pathname.startsWith('/settings/position/edit')) {
          isAuth = [MAINTAIN_POSITION].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/team/create') || req.nextUrl.pathname.startsWith('/settings/team/edit')) {
          isAuth = [MAINTAIN_TEAM].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/group/create') || req.nextUrl.pathname.startsWith('/settings/group/edit')) {
          isAuth = [MAINTAIN_GROUP].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/holiday/create') || req.nextUrl.pathname.startsWith('/settings/holiday/edit')) {
          isAuth = [MAINTAIN_HOLIDAY].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/user')) {
          isAuth = [MAINTAIN_USER].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/staff/user')) {
          isAuth = [MAINTAIN_USER].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics')) {
          isAuth = [
            GENERATE_LATE_START_REPORT,
            GENERATE_PROJECT_POTENTIAL_DELAY_REPORT,
            GENERATE_RESOURCE_OVERCONSUMPTION_REPORT,
            GENERATE_COST_AND_EXPENSE_REPORT,
            GENERATE_PROJECT_COMPLETION_REPORT,
            GENERATE_PROJECT_PANDL_REPORT,
            GENERATE_FINANCIAL_STATUS_REPORT,
            GENERATE_PROJECT_CASH_FLOW_REPORT,
            GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT,
            GENERATE_CROSS_TEAM_CHARGE_REPORT,
            G_PROJ_MANHOUR_SUMMARY_MONTHLY_REPORT,
            G_PROJ_MANHOUR_SUMMARY_DAILY_REPORT,
            GENERATE_LAST_MODIFIED_REPORT,
          ].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/LateStartReport')) {
          isAuth = [GENERATE_LATE_START_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/ProjectPotentialDelayReport')) {
          isAuth = [GENERATE_PROJECT_POTENTIAL_DELAY_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/ResourceOverconsumptionReport')) {
          isAuth = [GENERATE_RESOURCE_OVERCONSUMPTION_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/CostandExpenseReport')) {
          isAuth = [GENERATE_COST_AND_EXPENSE_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/ProjectCompletionReport')) {
          isAuth = [GENERATE_PROJECT_COMPLETION_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/ProjectPandLReport')) {
          isAuth = [GENERATE_PROJECT_PANDL_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/FinancialStatusReport')) {
          isAuth = [GENERATE_FINANCIAL_STATUS_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/ProjectCashFlowReport')) {
          isAuth = [GENERATE_PROJECT_CASH_FLOW_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/StaffMonthlyWorkHoursAnalysisReport')) {
          isAuth = [GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/CrossTeamChargeReport')) {
          isAuth = [GENERATE_CROSS_TEAM_CHARGE_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/ProjectManhourSummaryReport')) {
          isAuth = [G_PROJ_MANHOUR_SUMMARY_MONTHLY_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/ProjectMonthlyReport')) {
          isAuth = [G_PROJ_MANHOUR_SUMMARY_DAILY_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/analytics/LastModifiedReport')) {
          isAuth = [GENERATE_LAST_MODIFIED_REPORT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/settings/staff/edit')) {
          isAuth = [VIEW_STAFF_PROFILE].some((ability) => abilities.includes(ability));
        }
        
        if (req.nextUrl.pathname.startsWith('/invoice')) {
          isAuth = [IMPORT_INVOICE, IMPORT_RECEIPT].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/dashboard')) {
          isAuth = [VIEW_DASHBOARD_ALL, VIEW_DASHBOARD_SELF].some((ability) => abilities.includes(ability));
        }

        if (req.nextUrl.pathname.startsWith('/dashboard/ProjectResourceConsumptionRanking')) {
          isAuth = [VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING].some((ability) => abilities.includes(ability));
        } 
        return isAuth
      }
    }
  });

  // Matcher for using the auth middleware
  return PRIVATE_ROUTES.some((route) => req.nextUrl.pathname.startsWith(route))
    ? await authMiddleware(req, event) // Let auth middleware handle response
    : NextResponse.next(); // Return normal response
}
