import { APIRequestContext, Page } from '@playwright/test';

/**
 * Base API Helper
 * Cung cấp các HTTP methods cơ bản (GET, POST, PUT, DELETE)
 * Xử lý authentication và CSRF token tự động
 */
export class ApiBaseHelper {
    protected request: APIRequestContext;
    protected page: Page;
    protected baseURL: string;
    private csrfToken: string = '';

    constructor(page: Page, request: APIRequestContext) {
        this.page = page;
        this.request = request;
        // Fix: Remove trailing slash để tránh double slash
        this.baseURL = (process.env.BASE_URL || "https://qa.loprx.com").replace(/\/$/, '');
    }

    /**
     * Lấy CSRF token từ cookies hoặc meta tag
     */
    protected async getCsrfToken(): Promise<string> {
        if (this.csrfToken) return this.csrfToken;

        const cookies = await this.page.context().cookies();
        const csrfCookie = cookies.find(cookie => 
            cookie.name === 'XSRF-TOKEN' || cookie.name === 'csrf_token'
        );

        if (csrfCookie) {
            this.csrfToken = decodeURIComponent(csrfCookie.value);
            return this.csrfToken;
        }

        const metaToken = await this.page.locator('meta[name="csrf-token"]').getAttribute('content');
        if (metaToken) {
            this.csrfToken = metaToken;
            return this.csrfToken;
        }

        return '';
    }

    /**
     * Tạo headers chung với CSRF token
     */
    protected async getHeaders(contentType: string = 'application/json'): Promise<Record<string, string>> {
        const token = await this.getCsrfToken();
        
        const headers: Record<string, string> = {
            'Content-Type': contentType,
            'Accept': 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
        };

        if (token) {
            headers['X-CSRF-TOKEN'] = token;
        }

        return headers;
    }

    /**
     * GET request
     */
    async get(endpoint: string) {
        const headers = await this.getHeaders('application/json');
        const cookies = await this.page.context().cookies();
        
        const response = await this.request.get(`${this.baseURL}${endpoint}`, {
            headers: {
                ...headers,
                'Cookie': cookies.map(c => `${c.name}=${c.value}`).join('; ')
            }
        });

        return {
            status: response.status(),
            data: await response.json().catch(() => ({}))
        };
    }

    /**
     * POST request với multipart form data
     * Tự động thêm _token vào body
     */
    async post(endpoint: string, data: any, isMultipart: boolean = false) {
        const cookies = await this.page.context().cookies();
        const token = await this.getCsrfToken();
        
        let requestBody: any;
        let headers: Record<string, string> = {
            'Accept': 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
            'Cookie': cookies.map(c => `${c.name}=${c.value}`).join('; ')
        };

        if (isMultipart) {
            // Multipart form data - thêm _token vào body
            requestBody = {
                _token: token,
                ...data
            };
            
            // Không set Content-Type cho multipart, Playwright tự động add boundary
            if (token) {
                headers['X-CSRF-TOKEN'] = token;
            }
        } else {
            // JSON body
            requestBody = data;
            headers['Content-Type'] = 'application/json';
            if (token) {
                headers['X-CSRF-TOKEN'] = token;
            }
        }

        const response = await this.request.post(`${this.baseURL}${endpoint}`, {
            headers,
            ...(isMultipart ? { multipart: requestBody } : { data: requestBody })
        });

        const responseData = await response.json().catch(() => ({}));
        
        return {
            status: response.status(),
            data: responseData
        };
    }

    /**
     * PUT request
     */
    async put(endpoint: string, data: any) {
        const headers = await this.getHeaders('application/json');
        const cookies = await this.page.context().cookies();
        const token = await this.getCsrfToken();
        
        const response = await this.request.put(`${this.baseURL}${endpoint}`, {
            headers: {
                ...headers,
                'Cookie': cookies.map(c => `${c.name}=${c.value}`).join('; ')
            },
            data: {
                _token: token,
                ...data
            }
        });

        return {
            status: response.status(),
            data: await response.json().catch(() => ({}))
        };
    }

    /**
     * DELETE request
     */
    async delete(endpoint: string) {
        const headers = await this.getHeaders('application/json');
        const cookies = await this.page.context().cookies();
        
        const response = await this.request.delete(`${this.baseURL}${endpoint}`, {
            headers: {
                ...headers,
                'Cookie': cookies.map(c => `${c.name}=${c.value}`).join('; ')
            }
        });

        return {
            status: response.status(),
            data: await response.json().catch(() => ({}))
        };
    }
}