// actions.ts
"use server";
import { cache } from 'react';
import { serverFetchJson } from "@/app/utils/fetchUtil"; // 改为 serverFetchJson
import { BASE_API_URL } from "@/config/api";
//import { stockTakeDebugLog } from "@/components/StockTakeManagement/stockTakeDebugLog";

export interface RecordsRes<T> {
    records: T[];
    total: number;
}
export interface InventoryLotDetailResponse {
    id: number;
    inventoryLotId: number;
    itemId: number;
    itemCode: string;
    itemName: string;
    lotNo: string;
    expiryDate: string;
    productionDate: string;
    stockInDate: string;
    inQty: number;
    outQty: number;
    holdQty: number;
    availableQty: number;
    uom: string;
    warehouseCode: string;
    warehouseName: string;
    warehouseSlot: string;
    warehouseArea: string;
    warehouse: string;
    storeId?: string | null;
    varianceQty: number | null;
    status: string;
    remarks: string | null;
    stockTakeRecordStatus: string;
    stockTakeRecordId: number | null; 
    firstStockTakeQty: number | null; 
    secondStockTakeQty: number | null; 
    firstBadQty: number | null; 
    secondBadQty: number | null; 
    approverQty: number | null;
    approverBadQty: number | null;
    finalQty: number | null;
    bookQty: number | null;
    lastSelect?: number | null;
    stockTakeSection?: string | null;
    stockTakeSectionDescription?: string | null;
    stockTakerName?: string | null;
    /** ISO string or backend LocalDateTime array */
    stockTakeEndTime?: string | string[] | null;
    /** ISO string or backend LocalDateTime array */
    approverTime?: string | string[] | null;
}

/**
 * `approverInventoryLotDetailsAll*`：
 * - `total` = 全域 `inventory_lot_line` 中 `status = available` 筆數（與 DB COUNT 一致）
 * - `filteredRecordCount` = 目前 tab／篩選後筆數（分頁用）
 */
export interface ApproverInventoryLotDetailsRecordsRes extends RecordsRes<InventoryLotDetailResponse> {
    filteredRecordCount?: number;
    totalWaitingForApprover?: number;
    totalApproved?: number;
}

function normalizeApproverInventoryLotDetailsRes(
    raw: ApproverInventoryLotDetailsRecordsRes
): ApproverInventoryLotDetailsRecordsRes {
    const waiting = Number(raw.totalWaitingForApprover ?? 0) || 0;
    const approved = Number(raw.totalApproved ?? 0) || 0;
    return {
        records: Array.isArray(raw.records) ? raw.records : [],
        total: Number(raw.total ?? 0) || 0,
        filteredRecordCount: Number(raw.filteredRecordCount ?? 0) || 0,
        totalWaitingForApprover: waiting,
        totalApproved: approved,
    };
}

export const getInventoryLotDetailsBySection = async (
    stockTakeSection: string,
    stockTakeId?: number | null,
    pageNum?: number,
    pageSize?: number,
    stockTakeRoundId?: number | null
) => {
    /*
    console.log('🌐 [API] getInventoryLotDetailsBySection called with:', {
        stockTakeSection,
        stockTakeId,
        stockTakeRoundId,
        pageNum,
        pageSize
    });
    */
    const encodedSection = encodeURIComponent(stockTakeSection);
    let url = `${BASE_API_URL}/stockTakeRecord/inventoryLotDetailsBySection?stockTakeSection=${encodedSection}&pageNum=${pageNum}&pageSize=${pageSize}`;
    if (stockTakeId != null && stockTakeId > 0) {
        url += `&stockTakeId=${stockTakeId}`;
    }
    if (stockTakeRoundId != null && stockTakeRoundId > 0) {
        url += `&stockTakeRoundId=${stockTakeRoundId}`;
    }
    
    //console.log(' [API] Full URL:', url);
    
    const response = await serverFetchJson<RecordsRes<InventoryLotDetailResponse>>(
        url,
        {
            method: "GET",
        },
    );
    
    console.log('[API] Response received:', response);
    return response;
}
export interface SaveStockTakeRecordRequest {
    stockTakeRecordId?: number | null;
    inventoryLotLineId: number;
    qty: number;
    badQty: number;
    //stockTakerName: string;
    remark?: string | null;
}
export interface AllPickedStockTakeListReponse {
    id: number;
    stockTakeSession: string;
    lastStockTakeDate: string | null;
    status: string|null;
    approverName: string | null;
    currentStockTakeItemNumber: number;
    totalInventoryLotNumber: number;
    stockTakeId: number;
    stockTakeRoundId: number | null;
    stockTakerName: string | null;
    totalItemNumber: number;
    startTime: string | null;
    endTime: string | null;
    planStartDate: string | null;
    stockTakeSectionDescription: string | null;
    warehouseArea: string | null;
    storeId: string | null;
    reStockTakeTrueFalse: boolean;
}

/** 與 Picker 列表一致：區域描述、盤點區域、貨品編號／名稱（逗號多關鍵字由後端解析） */
export type ApproverInventoryLotDetailsQuery = {
    itemKeyword?: string | null;
    //itemKeyword?: string | null;
    sectionDescription?: string | null;
    stockTakeSections?: string | null;
    warehouseKeyword?: string | null;
    variancePercentTolerance?: string | null;
    varianceFilterInclusive?: boolean | null;
    varianceFilterStrict?: boolean | null;
};

function appendApproverInventoryLotQueryParams(
    params: URLSearchParams,
    query?: ApproverInventoryLotDetailsQuery | null
) {
    if (!query) return;
    if (query.itemKeyword != null && query.itemKeyword.trim() !== "") {
        params.append("itemKeyword", query.itemKeyword.trim());
    }
    if (query.warehouseKeyword != null && query.warehouseKeyword.trim() !== "") {
        params.append("warehouseKeyword", query.warehouseKeyword.trim());
    }
    if (
        query.sectionDescription != null &&
        query.sectionDescription !== "" &&
        query.sectionDescription !== "All"
    ) {
        params.append("sectionDescription", query.sectionDescription.trim());
    }
    if (query.stockTakeSections != null && query.stockTakeSections.trim() !== "") {
        params.append("stockTakeSections", query.stockTakeSections.trim());
    }
    if (query.variancePercentTolerance != null && query.variancePercentTolerance.trim() !== "") {
        params.append("variancePercentTolerance", query.variancePercentTolerance.trim());
    }
    if (query.varianceFilterInclusive === true) {
        params.append("varianceFilterInclusive", "true");
    }
    if (query.varianceFilterStrict === true) {
        params.append("varianceFilterStrict", "true");
    }
}

export const getApproverInventoryLotDetailsAll = async (
    stockTakeId?: number | null,
    pageNum: number = 0,
    pageSize: number = 100,
    query?: ApproverInventoryLotDetailsQuery | null
) => {
    const params = new URLSearchParams();
    params.append("pageNum", String(pageNum));
    params.append("pageSize", String(pageSize));
    if (stockTakeId != null && stockTakeId > 0) {
        params.append("stockTakeId", String(stockTakeId));
    }
    appendApproverInventoryLotQueryParams(params, query);

    const url = `${BASE_API_URL}/stockTakeRecord/approverInventoryLotDetailsAll?${params.toString()}`;
    const response = await serverFetchJson<ApproverInventoryLotDetailsRecordsRes>(
        url,
        {
            method: "GET",
        },
    );
    return normalizeApproverInventoryLotDetailsRes(response);
}
export const getApproverInventoryLotDetailsAllPending = async (
    stockTakeId?: number | null,
    pageNum: number = 0,
    pageSize: number = 50,
    query?: ApproverInventoryLotDetailsQuery | null
) => {
    const params = new URLSearchParams();
    params.append("pageNum", String(pageNum));
    params.append("pageSize", String(pageSize));
    if (stockTakeId != null && stockTakeId > 0) {
        params.append("stockTakeId", String(stockTakeId));
    }
    appendApproverInventoryLotQueryParams(params, query);
    const url = `${BASE_API_URL}/stockTakeRecord/approverInventoryLotDetailsAllPending?${params.toString()}`;
    const response = await serverFetchJson<ApproverInventoryLotDetailsRecordsRes>(url, { method: "GET" });
    return normalizeApproverInventoryLotDetailsRes(response);
}
export const getApproverInventoryLotDetailsAllApproved = async (
    stockTakeId?: number | null,
    pageNum: number = 0,
    pageSize: number = 50,
    query?: ApproverInventoryLotDetailsQuery | null
) => {
    const params = new URLSearchParams();
    params.append("pageNum", String(pageNum));
    params.append("pageSize", String(pageSize));
    if (stockTakeId != null && stockTakeId > 0) {
        params.append("stockTakeId", String(stockTakeId));
    }
    appendApproverInventoryLotQueryParams(params, query);
    const url = `${BASE_API_URL}/stockTakeRecord/approverInventoryLotDetailsAllApproved?${params.toString()}`;
    const response = await serverFetchJson<ApproverInventoryLotDetailsRecordsRes>(url, { method: "GET" });
    return normalizeApproverInventoryLotDetailsRes(response);
}

export const importStockTake = async (data: FormData) => {
    const importStockTake = await serverFetchJson<string>(
        `${BASE_API_URL}/stockTake/import`,
        {
            method: "POST",
            body: data,
        },
    );
    return importStockTake;
}

export const getStockTakeRecords = async () => {
    
    const stockTakeRecords = await serverFetchJson<AllPickedStockTakeListReponse[]>( // 改为 serverFetchJson
        `${BASE_API_URL}/stockTakeRecord/AllPickedStockOutRecordList`,
        {
            method: "GET",
        },
    );
    return stockTakeRecords;
}
export const getStockTakeRecordsPaged = async (
    pageNum: number,
    pageSize: number,
    params?: {
      sectionDescription?: string;
      stockTakeSections?: string;
      status?: string;
      area?: string;
      storeId?: string;
      onlyLatestRound?: boolean;
    }
  ) => {
    const searchParams = new URLSearchParams();
    searchParams.set("pageNum", String(pageNum));
    searchParams.set("pageSize", String(pageSize));
    if (params?.sectionDescription && params.sectionDescription !== "All") {
      searchParams.set("sectionDescription", params.sectionDescription);
    }
    if (params?.stockTakeSections?.trim()) {
      searchParams.set("stockTakeSections", params.stockTakeSections.trim());
    }
    if (params?.status && params.status !== "All") {
      searchParams.set("status", params.status);
    }
    if (params?.area?.trim()) {
      searchParams.set("area", params.area.trim());
    }
    if (params?.storeId && params.storeId !== "All") {
      searchParams.set("storeId", params.storeId);
    }
    if (params?.onlyLatestRound != null) {
      searchParams.set("onlyLatestRound", String(params.onlyLatestRound));
    }
    const url = `${BASE_API_URL}/stockTakeRecord/AllPickedStockOutRecordList?${searchParams.toString()}`;
    const res = await serverFetchJson<RecordsRes<AllPickedStockTakeListReponse>>(url, { method: "GET" });
    return res;
  };
export const getApproverStockTakeRecords = async () => {
    const stockTakeRecords = await serverFetchJson<AllPickedStockTakeListReponse[]>( // 改为 serverFetchJson
        `${BASE_API_URL}/stockTakeRecord/AllApproverStockTakeList`,
        {
            method: "GET",
        },
    );
    return stockTakeRecords;
}
export const getLatestApproverStockTakeHeader = async () => {
    return serverFetchJson<AllPickedStockTakeListReponse>(
        `${BASE_API_URL}/stockTakeRecord/LatestApproverStockTakeHeader`,
        { method: "GET" }
    );
}

export type LatestStockTakeRoundMeta = {
    stockTakeRoundId: number | null;
    planStartDate: string | null;
};

export const getLatestStockTakeRoundMeta = async () => {
    return serverFetchJson<LatestStockTakeRoundMeta>(
        `${BASE_API_URL}/stockTakeRecord/latestStockTakeRoundMeta`,
        { method: "GET" },
    );
};
export const createStockTakeForSections = async (
    sections: string[],
    stockTakeRoundName?: string | null,
    planStart?: string | null,
) => {
    const trimmedName = stockTakeRoundName?.trim();
    const trimmedPlanStart = planStart?.trim();
    return serverFetchJson<Map<string, string>>(
        `${BASE_API_URL}/stockTake/createForSections`,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                sections,
                ...(trimmedName ? { stockTakeRoundName: trimmedName } : {}),
                ...(trimmedPlanStart ? { planStart: trimmedPlanStart } : {}),
            }),
        },
    );
}

export const saveStockTakeRecord = async (
    request: SaveStockTakeRecordRequest,
    stockTakeId: number,
    stockTakerId: number
) => {
    try {
        const result = await serverFetchJson<any>(

            `${BASE_API_URL}/stockTakeRecord/saveStockTakeRecord?stockTakeId=${stockTakeId}&stockTakerId=${stockTakerId}`,
            {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(request),
            },
        );
        console.log('saveStockTakeRecord: request:', request);
        console.log('saveStockTakeRecord: stockTakeId:', stockTakeId);
        console.log('saveStockTakeRecord: stockTakerId:', stockTakerId);

        return result;
    } catch (error: any) {
        // 尝试从错误响应中提取消息
        if (error?.response) {
            try {
                const errorData = await error.response.json();
                const errorWithMessage = new Error(errorData.message || errorData.error || "Failed to save stock take record");
                (errorWithMessage as any).response = error.response;
                throw errorWithMessage;
            } catch {
                throw error;
            }
        }
        throw error;
    }
}
export interface BatchSaveStockTakeRecordRequest {
    stockTakeId: number;
    stockTakeSection: string;
    stockTakerId: number;
    //stockTakerName: string;
}

export interface BatchSaveStockTakeRecordResponse {
    successCount: number;
    errorCount: number;
    errors: string[];
}
export const batchSaveStockTakeRecords = cache(async (data: BatchSaveStockTakeRecordRequest) => {
    const r = await serverFetchJson<BatchSaveStockTakeRecordResponse>(`${BASE_API_URL}/stockTakeRecord/batchSaveStockTakeRecords`,
      {
        method: "POST",
        body: JSON.stringify(data),
        headers: { "Content-Type": "application/json" },
      })

    return r
  })

export interface BatchSavePickerStockTakeInputRequest {
    stockTakeId: number;
    stockTakeSection: string;
    stockTakerId: number;
    records: SaveStockTakeRecordRequest[];
}

export const batchSavePickerStockTakeInputs = async (
    data: BatchSavePickerStockTakeInputRequest
) => {
    try {
        return await serverFetchJson<BatchSaveStockTakeRecordResponse>(
            `${BASE_API_URL}/stockTakeRecord/batchSavePickerStockTakeInputs`,
            {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify(data),
            }
        );
    } catch (error: unknown) {
        if (error && typeof error === "object" && "response" in error) {
            const err = error as { response?: Response };
            if (err.response) {
                try {
                    const errorData = await err.response.json();
                    const errorWithMessage = new Error(
                        (errorData as { message?: string }).message ||
                            (errorData as { error?: string }).error ||
                            "Failed to batch save picker stock take inputs"
                    );
                    throw errorWithMessage;
                } catch (inner) {
                    if (inner instanceof Error && inner.message !== "Failed to batch save picker stock take inputs") {
                        throw inner;
                    }
                }
            }
        }
        throw error;
    }
};
  // Add these interfaces and functions

export interface SaveApproverStockTakeRecordRequest {
    stockTakeRecordId?: number | null;
    qty: number;
    badQty: number;
    approverId?: number | null;
    approverQty?: number | null;
    approverBadQty?: number | null;
    lastSelect?: number | null;
}

export interface BatchSaveApproverStockTakeRecordRequest {
    stockTakeId: number;
    stockTakeSection: string;
    approverId: number;
    variancePercentTolerance?: number | null;
}

export interface BatchSaveApproverStockTakeRecordResponse {
    successCount: number;
    errorCount: number;
    errors: string[];
}
/*
export interface BatchSaveApproverStockTakeAllRequest {
    stockTakeId: number;
    approverId: number;
    variancePercentTolerance?: number | null;
}
*/
export interface BatchSaveApproverStockTakeAllRequest {
    stockTakeId: number;
    approverId: number;
    // UI 用，batch 不應該用它來 skip
    variancePercentTolerance?: number | null;
    // 新增：讓 batch 只處理搜索結果那批
    itemKeyword?: string | null;
    warehouseKeyword?: string | null;
    sectionDescription?: string | null;
    stockTakeSections?: string | null; // 逗號字串
  }
export interface BatchSaveApproverStockTakeByIdsRequest {
    stockTakeId: number;
    approverId: number;
    recordIds?: number[];
    records?: SaveApproverStockTakeRecordRequest[];
}
export const saveApproverStockTakeRecord = async (
    request: SaveApproverStockTakeRecordRequest,
    stockTakeId: number
) => {
    try {
        const result = await serverFetchJson<any>(
            `${BASE_API_URL}/stockTakeRecord/saveApproverStockTakeRecord?stockTakeId=${stockTakeId}`,
            {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(request),
            },
        );

        return result;
    } catch (error: any) {
        if (error?.response) {
            try {
                const errorData = await error.response.json();
                const errorWithMessage = new Error(errorData.message || errorData.error || "Failed to save approver stock take record");
                (errorWithMessage as any).response = error.response;
                throw errorWithMessage;
            } catch {
                throw error;
            }
        }
        throw error;
    }
}

export const batchSaveApproverStockTakeRecords = cache(async (data: BatchSaveApproverStockTakeRecordRequest) => {
    return serverFetchJson<BatchSaveApproverStockTakeRecordResponse>(
        `${BASE_API_URL}/stockTakeRecord/batchSaveApproverStockTakeRecords`,
        {
            method: "POST",
            body: JSON.stringify(data),
            headers: { "Content-Type": "application/json" },
        }
    )
}
)

export const batchSaveApproverStockTakeRecordsAll = cache(async (data: BatchSaveApproverStockTakeAllRequest) => {
    const r = await serverFetchJson<BatchSaveApproverStockTakeRecordResponse>(
        `${BASE_API_URL}/stockTakeRecord/batchSaveApproverStockTakeRecordsAll`,
        {
            method: "POST",
            body: JSON.stringify(data),
            headers: { "Content-Type": "application/json" },
        }
    )

    return r
})

export const batchSaveApproverStockTakeRecordsByIds = cache(async (data: BatchSaveApproverStockTakeByIdsRequest) => {
    const r = await serverFetchJson<BatchSaveApproverStockTakeRecordResponse>(
        `${BASE_API_URL}/stockTakeRecord/batchSaveApproverStockTakeRecordsByIds`,
        {
            method: "POST",
            body: JSON.stringify(data),
            headers: { "Content-Type": "application/json" },
        }
    )
    return r
})

export const updateStockTakeRecordStatusToNotMatch = async (
    stockTakeRecordId: number
) => {
    try {
        const result = await serverFetchJson<any>(
            `${BASE_API_URL}/stockTakeRecord/updateStockTakeRecordStatusToNotMatch?stockTakeRecordId=${stockTakeRecordId}`,
            {
                method: "POST",
            },
        );
        return result;
    } catch (error: any) {
        if (error?.response) {
            try {
                const errorData = await error.response.json();
                const errorWithMessage = new Error(errorData.message || errorData.error || "Failed to update stock take record status");
                (errorWithMessage as any).response = error.response;
                throw errorWithMessage;
            } catch {
                throw error;
            }
        }
        throw error;
    }
}

export const getInventoryLotDetailsBySectionNotMatch = async (
    stockTakeSection: string,
    stockTakeId?: number | null,
    pageNum: number = 0,
    pageSize: number = 10,
    stockTakeRoundId?: number | null
) => {
    const encodedSection = encodeURIComponent(stockTakeSection);
    let url = `${BASE_API_URL}/stockTakeRecord/inventoryLotDetailsBySectionNotMatch?stockTakeSection=${encodedSection}&pageNum=${pageNum}`;
    
    // Only add pageSize if it's not "all" (which would be a large number)
    if (pageSize < 100000) {
        url += `&pageSize=${pageSize}`;
    }
    // If pageSize is large (meaning "all"), don't send it - backend will return all
    
    if (stockTakeId != null && stockTakeId > 0) {
        url += `&stockTakeId=${stockTakeId}`;
    }
    if (stockTakeRoundId != null && stockTakeRoundId > 0) {
        url += `&stockTakeRoundId=${stockTakeRoundId}`;
    }
    
    const response = await serverFetchJson<RecordsRes<InventoryLotDetailResponse>>(
        url,
        {
            method: "GET",
        },
    );
    return response;
}
export interface SearchStockTransactionResult {
    records: StockTransactionResponse[];
    total: number;
}
export interface SearchStockTransactionRequest {
    startDate: string | null;
    endDate: string | null;
    itemCode: string | null;
    itemName: string | null;
    type: string | null;
    pageNum: number;
    pageSize: number;
} 
export interface StockTransactionResponse {
    id: number;
    transactionType: string;
    itemId: number;
    itemCode: string | null;
    itemName: string | null;
    uomId?: number | null;
    uomDesc?: string | null;
    balanceQty: number | null;
    qty: number;
    type: string | null;
    status: string;
    transactionDate: string | null;
    date: string | null;  // 添加这个字段
    lotNo: string | null;
    stockInId: number | null;
    stockOutId: number | null;
    remarks: string | null;
}

export interface StockTransactionListResponse {
    records: RecordsRes<StockTransactionResponse>;
}

export const searchStockTransactions = cache(async (request: SearchStockTransactionRequest) => {
    const params = new URLSearchParams();
    
    if (request.itemCode) params.append("itemCode", request.itemCode);
    if (request.itemName) params.append("itemName", request.itemName);
    if (request.type) params.append("type", request.type);
    if (request.startDate) params.append("startDate", request.startDate);
    if (request.endDate) params.append("endDate", request.endDate);
    params.append("pageNum", String(request.pageNum || 0));
    params.append("pageSize", String(request.pageSize || 100));
    
    const queryString = params.toString();
    const url = `${BASE_API_URL}/stockTakeRecord/searchStockTransactions${queryString ? `?${queryString}` : ''}`;
    
    const response = await serverFetchJson<RecordsRes<StockTransactionResponse>>(
        url,
        {
            method: "GET",
            next: { tags: ["Stock Transaction List"] },
        }
    );
    // 回傳 records 與 total，供分頁正確顯示
    return {
        records: response?.records || [],
        total: response?.total ?? 0,
    };
});

