"use server";

import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";
import { serverFetchJson } from "@/app/utils/fetchUtil";
import { BASE_API_URL } from "@/config/api";
import { cache } from "react";
import { DetailedProdScheduleLineBomMaterialResult, DetailedProdScheduleLineResult, ScheduleType } from ".";
import { revalidateTag } from "next/cache";

export interface SearchProdSchedule {
  scheduleAt?: string;
  schedulePeriod?: string;
  schedulePeriodTo?: string;
  produceAt?: string;
  totalEstProdCount?: number;
  types?: ScheduleType[];
  pageSize?: number;
  pageNum?: number;
}

export interface ProdScheduleResult {
  id: number;
  scheduleAt: number[];
  schedulePeriod?: number[];
  schedulePeriodTo?: number[];
  produceAt: number[];
  totalEstProdCount: number;
  totalFGType: number;
  type: ScheduleType;
}

export interface ProdScheduleResultByPage {
  total: number;
  records: ProdScheduleResult[];
}

export interface ReleaseProdScheduleInputs {
  id: number;
  demandQty: number;
}

export interface ReleaseProdScheduleReq {
  id: number;
}

export interface print6FilesReq {
  itemCode: 'string',
  lotNo: 'string',
  expiryDate: 'string',
  productName: 'string'
}

export interface ReleaseProdScheduleResponse {
  id: number;
  code: string;
  entity: {
    prodScheduleLines: DetailedProdScheduleLineResult[];
  };
  message: string;
}

export interface ReleaseProdScheduleRsp {
  id: number;
  code: string;
  message: string;
}

export interface SaveProdScheduleResponse {
  id: number;
  code: string;
  entity: {
    bomMaterials: DetailedProdScheduleLineBomMaterialResult[]
  };
  message: string;
}

export const fetchProdSchedules = cache(
  async (data: SearchProdSchedule | null) => {
    const params = convertObjToURLSearchParams<SearchProdSchedule>(data);
    // console.log(params)
    return serverFetchJson<ProdScheduleResultByPage>(
      `${BASE_API_URL}/productionSchedule/getRecordByPage?${params}`,
      {
        method: "GET",
        headers: { "Content-Type": "application/json" },
        next: {
          tags: ["prodSchedules"],
        },
      },
    );
  },
);

export const fetchRoughProdSchedules = cache(
  async (data: SearchProdSchedule | null) => {
    const params = convertObjToURLSearchParams<SearchProdSchedule>(data);
    // console.log(params)
    return serverFetchJson<ProdScheduleResultByPage>(
      `${BASE_API_URL}/productionSchedule/getRecordByPage/rough?${params}`,
      {
        method: "GET",
        headers: { "Content-Type": "application/json" },
        next: {
          tags: ["roughProdSchedules"],
        },
      },
    );
  },
);

export const fetchDetailedProdSchedules = cache(
  async (data: SearchProdSchedule | null) => {
    const params = convertObjToURLSearchParams<SearchProdSchedule>(data);
    // console.log(params)
    return serverFetchJson<ProdScheduleResultByPage>(
      `${BASE_API_URL}/productionSchedule/getRecordByPage/detailed?${params}`,
      {
        method: "GET",
        headers: { "Content-Type": "application/json" },
        next: {
          tags: ["detailedProdSchedules"],
        },
      },
    );
  },
);

export const testRoughSchedule = cache(async () => {
  return serverFetchJson(
    `${BASE_API_URL}/productionSchedule/testRoughSchedule`,
    {
      method: "GET",
      headers: { "Content-Type": "application/json" },
      next: {
        tags: ["roughProdSchedules"],
      },
    },
  );
});

export const testDetailedSchedule = cache(async (date?: string) => {
  const queryStr = convertObjToURLSearchParams({genDate: date})
  return serverFetchJson(
    `${BASE_API_URL}/productionSchedule/testDetailedSchedule?${queryStr}`,
    {
      method: "GET",
      headers: { "Content-Type": "application/json" },
      next: {
        tags: ["detailedProdSchedules"],
      },
    },
  );
});

export const getFile6 = cache(async (
  token: string | "", 
  data: print6FilesReq
) => {
  const queryStr = convertObjToURLSearchParams(data)
  return serverFetchJson(
    `${BASE_API_URL}/plastic/get-printer6?${queryStr}`,
    {
      method: "GET",
      headers: { 
        "Content-Type": "application/json",
        "Authorization": `Bearer ${token}`
      }, 
    },
  );
});

export const releaseProdScheduleLine = cache(async (data: ReleaseProdScheduleInputs) => {
  const response = serverFetchJson<ReleaseProdScheduleResponse>(
    `${BASE_API_URL}/productionSchedule/detail/detailed/releaseLine`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    }
  );

  revalidateTag("detailedProdSchedules");
  revalidateTag("prodSchedule");

  return response;
})

export const releaseProdSchedule = cache(async (data: ReleaseProdScheduleReq) => {
  const response = serverFetchJson<ReleaseProdScheduleRsp>(
    `${BASE_API_URL}/productionSchedule/detail/detailed/release`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    }
  );

  //revalidateTag("detailedProdSchedules");
  //revalidateTag("prodSchedule");

  return response;
})

export const exportProdSchedule = async (
  token: string | null, 
  inputs: any, 
  prodHeaders: string[], 
  matHeaders: string[]
) => {
  if (!token) throw new Error("No access token found");

  const response = await fetch(`${BASE_API_URL}/productionSchedule/export-prod-schedule`, {
    method: "POST",
    headers: { 
      "Content-Type": "application/json", // Critical for @RequestBody
      "Accept": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      "Authorization": `Bearer ${token}`
    },
    // Send everything in one object
    body: JSON.stringify({ 
      ...inputs, 
      prodHeaders, 
      matHeaders 
    })
  });

  if (!response.ok) throw new Error(`Backend error: ${response.status}`);

  const arrayBuffer = await response.arrayBuffer();
  return Buffer.from(arrayBuffer).toString('base64');
};

export const saveProdScheduleLine = cache(async (data: ReleaseProdScheduleInputs) => {
  const response = serverFetchJson<SaveProdScheduleResponse>(
    `${BASE_API_URL}/productionSchedule/detail/detailed/save`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    }
  );

  revalidateTag("detailedProdSchedules");
  revalidateTag("prodSchedule");

  return response;
})