import {
  HttpRequest,
  HttpResponseInit,
  InvocationContext,
  app,
  HttpMethod,
} from "@azure/functions";
import { licenseAutoAllocationProcessing } from "./licenseAutoAllocation";
import * as dotenv from "dotenv";
import { DataSource } from "typeorm";
import { User } from "../entity/user.entity";
import { Account } from "../entity/account.entity";
import { License, LicenseAllocationHistory } from "../entity/license.entity";
import { HTTP_METHODS, HTTP_STATUS_CODES } from "../constants";

export async function licenseAutoAllocationManualRetry(
  req: HttpRequest,
  context: InvocationContext
): Promise<HttpResponseInit> {
  context.log(req);
  try {
    if (req.method === HTTP_METHODS.POST) {
      const queryParams = new URLSearchParams(req.url.split("&")[1]); // クエリパラメータを取得
      const requestedDate = queryParams.get("date");
      context.log("requestedDate: " + requestedDate);
      let dateToTrigger: Date;
      if (requestedDate) {
        // パラメータのチェックを行う（YYYY-MM-DD形式）
        if (!requestedDate.match(/^\d{4}-\d{2}-\d{2}$/)) {
          context.log("Invalid date format.");
          return {
            status: HTTP_STATUS_CODES.BAD_REQUEST,
            body: "Invalid date format.",
          };
        }
        dateToTrigger = new Date(requestedDate);
      } else {
        dateToTrigger = new Date();
      }
      context.log("[IN]licenseAutoAllocationManualRetry");
      dotenv.config({ path: ".env" });
      dotenv.config({ path: ".env.local", override: true });
      let datasource: DataSource;
      try {
        datasource = new DataSource({
          type: "mysql",
          host: process.env.DB_HOST,
          port: Number(process.env.DB_PORT),
          username: process.env.DB_USERNAME,
          password: process.env.DB_PASSWORD,
          database: process.env.DB_NAME,
          entities: [User, Account, License, LicenseAllocationHistory],
        });
        await datasource.initialize();
      } catch (e) {
        context.log("database initialize failed.");
        context.error(e);
        throw e;
      }

      await licenseAutoAllocationProcessing(context, datasource, dateToTrigger);
      context.log("Automatic license allocation has been triggered.");
      return {
        status: HTTP_STATUS_CODES.OK,
        body: "Automatic license allocation has been triggered.",
      };
    } else {
      context.log("Please use the POST method.");
      return {
        status: HTTP_STATUS_CODES.BAD_REQUEST,
        body: "Please use the POST method.",
      };
    }
  } catch (e) {
    context.log("licenseAutoAllocationManualRetry failed.");
    context.error(e);
    return {
      status: HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR,
      body: "licenseAutoAllocationManualRetry failed.",
    };
  } finally {
    context.log("[OUT]licenseAutoAllocationManualRetry");
  }
}

// httpトリガは定時処理licenseAutoAllocationの異常時の手動再実行用
app.http("licenseAutoAllocationManualRetry", {
  methods: [HTTP_METHODS.POST as HttpMethod],
  authLevel: "function",
  handler: licenseAutoAllocationManualRetry,
});
