import { apiClient, ensureCsrfCookie } from './client';

/**
 * API-вызовы для DealController.
 *
 * На MVP без auth — tenant_id передаётся параметром (на prod возьмётся из
 * middleware → backend параметр исчезнет).
 */

export interface CreateDealPayload {
    tenant_id: number;
    project_name: string;
    phone: string;
    contact_name?: string;
    status?: string;
    manager_id?: number;
    comment?: string;
}

export interface CreatedDeal {
    id: number;
    tenant_id: number;
    project_id: number;
    phone: string;
    status: string;
    contact_name: string | null;
    manager_id: number | null;
    received_at: string;
}

export async function createDeal(payload: CreateDealPayload): Promise<CreatedDeal> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ deal: CreatedDeal; message: string }>('/api/deals', payload);
    return data.deal;
}

export interface BulkDeleteDealsPayload {
    tenant_id: number;
    ids: number[];
}

export interface BulkDeleteDealsResponse {
    deleted: number;
    requested: number;
}

/** Bulk soft-delete. Возвращает {deleted, requested} — deleted может быть < requested
 *  если часть id чужие или уже удалены (NO-OP). */
export async function bulkDeleteDeals(payload: BulkDeleteDealsPayload): Promise<BulkDeleteDealsResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.delete<BulkDeleteDealsResponse>('/api/deals', { data: payload });
    return data;
}

export interface BulkRestoreDealsPayload {
    tenant_id: number;
    ids: number[];
}

export interface BulkRestoreDealsResponse {
    restored: number;
    requested: number;
}

/** Bulk restore soft-deleted сделок. NO-OP idempotent для не-удалённых. */
export async function bulkRestoreDeals(payload: BulkRestoreDealsPayload): Promise<BulkRestoreDealsResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<BulkRestoreDealsResponse>('/api/deals/restore', payload);
    return data;
}

export interface ExportDealsPayload {
    tenant_id: number;
    ids: number[];
    format?: 'csv' | 'xlsx';
}

export interface UpdateDealPayload {
    tenant_id: number;
    comment?: string | null;
    manager_id?: number | null;
    status?: string;
}

export async function updateDeal(id: number, payload: UpdateDealPayload): Promise<ApiDealDetail> {
    await ensureCsrfCookie();
    const { data } = await apiClient.patch<{ deal: ApiDealDetail }>(`/api/deals/${id}`, payload);
    return data.deal;
}

export interface TransitionDealsPayload {
    tenant_id: number;
    ids: number[];
    status: string;
}

export interface TransitionDealsResponse {
    updated: number;
    requested: number;
    status: string;
}

/** Bulk status-update. Возвращает {updated, requested} — updated может быть < requested
 *  если часть id'шников чужие или уже в этом статусе (NO-OP). */
export async function transitionDeals(payload: TransitionDealsPayload): Promise<TransitionDealsResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<TransitionDealsResponse>('/api/deals/transition', payload);
    return data;
}

/** CSV-export. Возвращает строку с BOM — caller заворачивает в Blob+download. */
export async function exportDeals(payload: ExportDealsPayload): Promise<string> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<string>(
        '/api/deals/export',
        { ...payload, format: 'csv' },
        { responseType: 'text' },
    );
    return data;
}

/** XLSX-export. Возвращает Blob (binary) — caller триггерит download. */
export async function exportDealsXlsx(payload: Omit<ExportDealsPayload, 'format'>): Promise<Blob> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<Blob>(
        '/api/deals/export',
        { ...payload, format: 'xlsx' },
        { responseType: 'blob' },
    );
    return data;
}

export interface ExportDealsByRangePayload {
    tenant_id: number;
    received_from?: string;
    received_to?: string;
    format: 'csv' | 'xlsx';
}

/**
 * Экспорт сделок по диапазону дат поставки. format='xlsx' → Blob, 'csv' → строка.
 */
export async function exportDealsByRange(payload: ExportDealsByRangePayload): Promise<Blob | string> {
    await ensureCsrfCookie();
    if (payload.format === 'xlsx') {
        const { data } = await apiClient.post<Blob>('/api/deals/export', payload, { responseType: 'blob' });
        return data;
    }
    const { data } = await apiClient.post<string>('/api/deals/export', payload, { responseType: 'text' });
    return data;
}

export interface ApiDeal {
    id: number;
    tenant_id: number;
    project_id: number;
    project_name: string | null;
    phone: string;
    contact_name: string | null;
    status: string;
    manager_id: number | null;
    manager_name: string | null;
    manager_initials: string | null;
    received_at: string | null;
    comment: string | null;
    city: string | null;
    // F2: стоимость лида в копейках (снимок rub-списания из lead_charges) или null
    // (prepaid/не списано). Отдаётся deal-detail (show); в листинге может отсутствовать.
    cost_kopecks?: number | null;
    project_signal_type: string | null;
    project_signal_identifier?: string | null;
    project_sms_keyword?: string | null;
    project_sms_senders?: string[] | null;
}

export interface ApiDealEvent {
    id: number;
    event: string;
    context: Record<string, unknown> | null;
    created_at: string | null;
    actor: { id: number; name: string; initials: string } | null;
}

export interface ApiDealDetail extends ApiDeal {
    comment: string | null;
    assigned_at: string | null;
}

export interface GetDealResponse {
    deal: ApiDealDetail;
    events: ApiDealEvent[];
}

export async function getDeal(id: number, tenantId: number): Promise<GetDealResponse> {
    const { data } = await apiClient.get<GetDealResponse>(`/api/deals/${id}`, {
        params: { tenant_id: tenantId },
    });
    return data;
}

export interface ListDealsParams {
    tenantId: number;
    statusIn?: string[];
    projectId?: number;
    managerId?: number;
    search?: string;
    /** Диапазон дат поставки (received_at). ISO-дата 'YYYY-MM-DD'. */
    receivedFrom?: string;
    receivedTo?: string;
    limit?: number;
    offset?: number;
    /** «Корзина» — вернуть ТОЛЬКО soft-deleted сделки. */
    onlyDeleted?: boolean;
}

export interface ListDealsResponse {
    deals: ApiDeal[];
    total: number;
    limit: number;
    offset: number;
}

export async function listDeals(params: ListDealsParams): Promise<ListDealsResponse> {
    const { data } = await apiClient.get<ListDealsResponse>('/api/deals', {
        params: {
            tenant_id: params.tenantId,
            status_in: params.statusIn,
            project_id: params.projectId,
            manager_id: params.managerId,
            search: params.search,
            received_from: params.receivedFrom,
            received_to: params.receivedTo,
            limit: params.limit,
            offset: params.offset,
            only_deleted: params.onlyDeleted ? 'true' : undefined,
        },
    });
    return data;
}

export interface ApiManager {
    id: number;
    email: string;
    first_name: string | null;
    last_name: string | null;
    name: string;
    initials: string;
}

export async function listManagers(tenantId: number): Promise<ApiManager[]> {
    const { data } = await apiClient.get<{ managers: ApiManager[] }>('/api/managers', {
        params: { tenant_id: tenantId },
    });
    return data.managers;
}

export interface ApiProject {
    id: number;
    name: string;
    tag: string | null;
    type: string;
}

export async function listProjects(tenantId: number): Promise<ApiProject[]> {
    // ProjectController::index() отдаёт { data: ProjectResource::collection(...) }.
    // `?? []` — защита от undefined.map в DealsView при нештатном ответе.
    const { data } = await apiClient.get<{ data: ApiProject[] }>('/api/projects', {
        params: { tenant_id: tenantId },
    });
    return data.data ?? [];
}

/**
 * Лёгкий count-only запрос для бейджа «Сделки» в AppSidebar (audit B2).
 * Backend пропускает SELECT строк — отдаёт только COUNT(*).
 */
export async function fetchDealsCount(tenantId: number): Promise<number> {
    const { data } = await apiClient.get<{ total: number }>('/api/deals', {
        params: { tenant_id: tenantId, count_only: 1 },
    });
    return data.total;
}
