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

/**
 * API-вызовы для админских endpoint'ов SaaS (см. ImpersonationController).
 *
 * На MVP вызываются без auth:saas-admin middleware (см. routes/web.php).
 * Production: middleware('auth:saas-admin') + cookie session — apiClient уже
 * настроен на withCredentials.
 */

export interface ImpersonationInitPayload {
    tenant_id: number;
    requested_by: number; // на MVP параметром; на prod — request()->user()->id
    reason: string; // ≥30 chars (валидируется на backend)
}

export interface ImpersonationInitResponse {
    token_id: number;
    expires_at: string; // ISO8601
    sent_to_email: string;
    /** dev-only: исчезнет после интеграции MailService на prod */
    _dev_plain_code?: string;
}

export async function impersonationInit(payload: ImpersonationInitPayload): Promise<ImpersonationInitResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<ImpersonationInitResponse>('/api/admin/impersonation/init', payload);
    return data;
}

export interface ImpersonationVerifyPayload {
    token_id: number;
    code: string; // 6 цифр
}

export interface ImpersonationVerifyResponse {
    token_id: number;
    tenant_id: number;
    used_at: string;
    message: string;
    machine_token: string;
    expires_at: string;
}

export async function impersonationVerify(payload: ImpersonationVerifyPayload): Promise<ImpersonationVerifyResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<ImpersonationVerifyResponse>('/api/admin/impersonation/verify', payload);
    return data;
}

export interface ImpersonationEndResponse {
    token_id: number;
    session_ended_at: string;
    message: string;
}

export async function impersonationEnd(tokenId: number): Promise<ImpersonationEndResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<ImpersonationEndResponse>('/api/admin/impersonation/end', {
        token_id: tokenId,
    });
    return data;
}

export interface ImpersonationActiveSession {
    token_id: number;
    tenant_id: number;
    tenant_name: string | null;
    requested_by: number;
    reason: string;
    sent_to_email: string;
    used_at: string;
    expires_at: string;
}

export interface ImpersonationRecentSession {
    token_id: number;
    tenant_id: number;
    tenant_name: string | null;
    requested_by: number;
    reason: string;
    used_at: string;
    session_ended_at: string;
    duration_seconds: number | null;
}

export async function impersonationActive(): Promise<ImpersonationActiveSession[]> {
    const { data } = await apiClient.get<{ sessions: ImpersonationActiveSession[] }>('/api/admin/impersonation/active');
    return data.sessions;
}

export async function impersonationRecent(): Promise<ImpersonationRecentSession[]> {
    const { data } = await apiClient.get<{ sessions: ImpersonationRecentSession[] }>('/api/admin/impersonation/recent');
    return data.sessions;
}

// === SaaS-admin → Тенанты: lookup для AdminTenantsView ===

export interface AdminTenant {
    id: number;
    subdomain: string;
    organization_name: string;
    contact_email: string;
    status: string;
    balance_rub: string;
    balance_leads: number;
    is_trial: boolean;
    last_activity_at: string | null;
    tariff_id: number | null;
    tariff_name: string | null;
    /** price_monthly активного тарифа если не-trial; иначе null. */
    mrr_rub: string | null;
    desired_daily_numbers: number | null;
    chargeback_unrecovered_rub: string;
    created_at: string | null;
}

interface AdminTenantsStats {
    total: number;
    active: number;
    trial: number;
    overdue: number;
}

export interface ListAdminTenantsParams {
    status?: string;
    /** Производные статусы UI (trial/overdue/active/suspended), csv — серверный multi-фильтр. */
    statuses?: string;
    /** Имена тарифов (tariff_plans.name), csv — серверный multi-фильтр. */
    tariffs?: string;
    search?: string;
    limit?: number;
    offset?: number;
}

export interface ListAdminTenantsResponse {
    tenants: AdminTenant[];
    total: number;
    limit: number;
    offset: number;
    stats: AdminTenantsStats;
}

export async function listAdminTenants(params: ListAdminTenantsParams = {}): Promise<ListAdminTenantsResponse> {
    const { data } = await apiClient.get<ListAdminTenantsResponse>('/api/admin/tenants', { params });
    return data;
}

// === SaaS-admin → Тенанты → детали (для AdminTenantDetailView) ===

export interface ApiTenantUser {
    id: number;
    email: string;
    first_name: string | null;
    last_name: string | null;
    is_active: boolean;
    totp_enabled: boolean;
    last_active_at: string | null;
    last_login_at: string | null;
}

export interface ApiTenantProject {
    id: number;
    name: string;
    tag: string | null;
    is_active: boolean;
    daily_limit_target: number;
    suppliers_count: number;
    leads_today: number;
}

export interface ApiTenantBalanceTx {
    id: number;
    type: string;
    amount_rub: string;
    amount_leads: number;
    balance_rub_after: string | null;
    description: string | null;
    created_at: string;
}

export interface ApiTenantActivityEvent {
    id: number;
    event: string;
    deal_id: number;
    actor_email: string | null;
    context: Record<string, unknown> | null;
    created_at: string;
}

interface ApiTenantMetrics {
    leads_today: number;
    leads_this_week: number;
    leads_this_month: number;
    avg_lead_cost_rub: number | null;
    runway_days: number | null;
}

export interface AdminTenantDetailResponse {
    tenant: AdminTenant;
    users: ApiTenantUser[];
    projects: ApiTenantProject[];
    balance_history: ApiTenantBalanceTx[];
    activity: ApiTenantActivityEvent[];
    metrics: ApiTenantMetrics;
}

export async function getAdminTenantDetail(subdomain: string): Promise<AdminTenantDetailResponse> {
    const { data } = await apiClient.get<AdminTenantDetailResponse>(
        `/api/admin/tenants/${encodeURIComponent(subdomain)}`,
    );
    return data;
}

// === SaaS-admin → Биллинг: aggregates пополнений/списаний ===

export interface ApiAdminBillingTenant {
    id: number;
    subdomain: string;
    organization_name: string;
    contact_email: string;
    status: string;
    balance_rub: string;
    tariff_id: number | null;
    tariff_name: string | null;
    mrr_rub: string;
    monthly_topups_rub: string;
    monthly_charges_rub: string;
    last_payment_at: string | null;
    chargeback_unrecovered_rub: string;
}

interface ApiAdminBillingSummary {
    total_mrr_rub: string;
    monthly_revenue_rub: string;
    overdue_count: number;
    refunds_count_30d: number;
}

export interface ListAdminBillingResponse {
    tenants: ApiAdminBillingTenant[];
    summary: ApiAdminBillingSummary;
}

export async function listAdminBilling(search = ''): Promise<ListAdminBillingResponse> {
    const { data } = await apiClient.get<ListAdminBillingResponse>('/api/admin/billing', {
        params: { search },
    });
    return data;
}

// === SaaS-admin → Инциденты ===

export interface ApiAdminIncident {
    id: number;
    incident_id: string;
    type: string;
    severity: 'low' | 'medium' | 'high' | 'critical';
    summary: string;
    started_at: string;
    detected_at: string;
    resolved_at: string | null;
    status: 'open' | 'investigating' | 'resolved';
    affected_tenants_count: number;
    affected_users_count: number | null;
    rkn_notified: boolean;
    rkn_notified_at: string | null;
    rkn_deadline_at: string | null;
}

interface ApiAdminIncidentsSummary {
    open: number;
    investigating: number;
    rkn_pending: number;
    total_unresolved: number;
}

export interface ListAdminIncidentsParams {
    type?: string;
    severity?: string;
    unresolved_only?: boolean;
    limit?: number;
    offset?: number;
}

export interface ListAdminIncidentsResponse {
    incidents: ApiAdminIncident[];
    total: number;
    limit: number;
    offset: number;
    summary: ApiAdminIncidentsSummary;
}

export async function listAdminIncidents(params: ListAdminIncidentsParams = {}): Promise<ListAdminIncidentsResponse> {
    const { data } = await apiClient.get<ListAdminIncidentsResponse>('/api/admin/incidents', { params });
    return data;
}

// === SaaS-admin → Система: system_settings edit-flow ===

export interface SystemSetting {
    key: string;
    value: string;
    type: 'int' | 'string' | 'decimal' | 'bool' | 'json';
    description: string | null;
    updated_at: string;
    updated_by: number | null;
}

export async function listSystemSettings(): Promise<SystemSetting[]> {
    const { data } = await apiClient.get<{ settings: SystemSetting[] }>('/api/admin/system-settings');
    return data.settings;
}

export interface UpdateSystemSettingPayload {
    value: string;
    reason: string; // ≥30 chars
    admin_user_id: number; // на prod удалится
}

export interface UpdateSystemSettingResponse {
    key: string;
    value: string;
    previous_value: string;
    updated_at: string;
    message: string;
}

export async function updateSystemSetting(
    key: string,
    payload: UpdateSystemSettingPayload,
): Promise<UpdateSystemSettingResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.put<UpdateSystemSettingResponse>(
        `/api/admin/system-settings/${encodeURIComponent(key)}`,
        payload,
    );
    return data;
}

// === SaaS-admin → Биллинг: row-actions (Sprint 3D G4) ===

export interface AdminTariffPlan {
    id: number;
    name: string;
    price_monthly: string;
}

export async function listAdminTariffPlans(): Promise<AdminTariffPlan[]> {
    const { data } = await apiClient.get<{ plans: AdminTariffPlan[] }>('/api/admin/billing/tariff-plans');
    return data.plans;
}

export async function updateTenantStatus(
    id: number,
    status: 'active' | 'suspended',
    reason: string,
): Promise<{ id: number; status: string }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.patch<{ id: number; status: string }>(`/api/admin/billing/tenants/${id}/status`, {
        status,
        reason,
    });
    return data;
}

export async function refundTenant(
    id: number,
    amountRub: number,
    reason: string,
): Promise<{ id: number; balance_rub: string; transaction_id: number }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ id: number; balance_rub: string; transaction_id: number }>(
        `/api/admin/billing/tenants/${id}/refund`,
        { amount_rub: amountRub, reason },
    );
    return data;
}

export async function updateTenantBalance(
    id: number,
    payload: { balance_rub: string; reason?: string },
): Promise<{ id: number; balance_rub: string; delta: string; transaction_id: number }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.patch<{
        id: number;
        balance_rub: string;
        delta: string;
        transaction_id: number;
    }>(`/api/admin/tenants/${id}/balance`, payload);
    return data;
}

export async function changeTenantTariff(
    id: number,
    tariffId: number,
    reason: string,
): Promise<{ id: number; tariff_id: number; tariff_name: string }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.patch<{ id: number; tariff_id: number; tariff_name: string }>(
        `/api/admin/billing/tenants/${id}/tariff`,
        { tariff_id: tariffId, reason },
    );
    return data;
}

// === SaaS-admin → Инциденты: detail-view + РКН-notify (Sprint 3D G5/G6) ===

export interface ApiIncidentAffectedTenant {
    id: number;
    organization_name: string;
}

export interface ApiAdminIncidentDetail {
    id: number;
    incident_id: string;
    type: string;
    severity: 'low' | 'medium' | 'high' | 'critical';
    summary: string;
    root_cause: string | null;
    postmortem_url: string | null;
    started_at: string;
    detected_at: string;
    resolved_at: string | null;
    status: 'open' | 'investigating' | 'resolved';
    affected_tenants: ApiIncidentAffectedTenant[];
    affected_users_count: number | null;
    notification_sent_at: string | null;
    rkn_notified: boolean;
    rkn_notified_at: string | null;
    rkn_deadline_at: string | null;
    created_by_admin: string | null;
    closed_by_admin: string | null;
    created_at: string | null;
    updated_at: string | null;
}

export async function getAdminIncidentDetail(id: number): Promise<ApiAdminIncidentDetail> {
    const { data } = await apiClient.get<{ incident: ApiAdminIncidentDetail }>(`/api/admin/incidents/${id}`);
    return data.incident;
}

export async function notifyIncidentRkn(id: number): Promise<ApiAdminIncidentDetail> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ incident: ApiAdminIncidentDetail }>(
        `/api/admin/incidents/${id}/rkn-notify`,
        {},
    );
    return data.incident;
}

// === SaaS-admin → Тарифная сетка (Plan 4 / Sprint 5C G3) ===

export interface AdminPricingTier {
    tier_no: number;
    leads_in_tier: number | null;
    price_per_lead_kopecks: number;
    effective_from: string;
}

export interface PricingTiersResponse {
    active: AdminPricingTier[];
    scheduled: Record<string, AdminPricingTier[]>;
}

export interface PricingTierEditorRow {
    tier_no: number;
    leads_in_tier: number | null;
    price_rub: string;
}

export async function getPricingTiers(): Promise<PricingTiersResponse> {
    const { data } = await apiClient.get<{ data: PricingTiersResponse }>('/api/admin/pricing-tiers');
    return { active: data.data.active, scheduled: data.data.scheduled ?? {} };
}

export async function createPricingTiers(
    tiers: PricingTierEditorRow[],
    effectiveFrom?: string,
): Promise<{ effective_from: string }> {
    await ensureCsrfCookie();
    const payload: { tiers: PricingTierEditorRow[]; effective_from?: string } = { tiers };
    if (effectiveFrom) payload.effective_from = effectiveFrom;
    const { data } = await apiClient.post<{ effective_from: string }>('/api/admin/pricing-tiers', payload);
    return data;
}

export async function deleteScheduledPricingTier(effectiveFrom: string): Promise<void> {
    await ensureCsrfCookie();
    await apiClient.delete(`/api/admin/pricing-tiers/scheduled/${effectiveFrom}`);
}

// === SaaS-admin → Цены поставщиков (Plan 4 / Sprint 5C G3) ===

export interface AdminSupplier {
    id: number;
    code: string;
    name: string;
    cost_rub: string;
    quality_score: string;
    is_active: boolean;
}

export async function getAdminSuppliers(): Promise<AdminSupplier[]> {
    const { data } = await apiClient.get<{ data: AdminSupplier[] }>('/api/admin/suppliers');
    return data.data;
}

export async function updateAdminSupplier(
    id: number,
    payload: { cost_rub: string; quality_score: string; is_active: boolean },
): Promise<AdminSupplier> {
    await ensureCsrfCookie();
    const { data } = await apiClient.patch<{ data: AdminSupplier }>(`/api/admin/suppliers/${id}`, payload);
    return data.data;
}

// ---------------------------------------------------------------------------
// 152-ФЗ: обращения субъектов ПДн
// ---------------------------------------------------------------------------

export interface PdSubjectRequest {
    id: number;
    received_at: string;
    subject_email: string | null;
    subject_phone: string | null;
    subject_full_name: string | null;
    request_type: 'access' | 'rectification' | 'deletion' | 'objection';
    description: string | null;
    status: 'received' | 'in_progress' | 'completed' | 'rejected';
    tenant_id: number | null;
    assigned_admin_id: number | null;
    response_text: string | null;
    deadline_at: string;
    completed_at: string | null;
    processing_restricted: boolean;
}

export interface ListPdRequestsResponse {
    data: PdSubjectRequest[];
    total: number;
    limit: number;
    offset: number;
}

export interface CreatePdRequestPayload {
    subject_email?: string;
    subject_phone?: string;
    subject_full_name?: string;
    request_type: 'access' | 'rectification' | 'deletion' | 'objection';
    description?: string;
    tenant_id?: number | null;
}

export interface EraseSubjectResult {
    message: string;
    counts: { users: number; leads: number; deals: number; webhook_log: number };
}

export async function listPdSubjectRequests(
    params: { status?: string; request_type?: string; limit?: number; offset?: number } = {},
): Promise<ListPdRequestsResponse> {
    const { data } = await apiClient.get<ListPdRequestsResponse>('/api/admin/pd-subject-requests', { params });
    return data;
}

export async function createPdSubjectRequest(payload: CreatePdRequestPayload): Promise<PdSubjectRequest> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ data: PdSubjectRequest }>('/api/admin/pd-subject-requests', payload);
    return data.data;
}

export async function executePdErasure(id: number, adminUserId?: number): Promise<EraseSubjectResult> {
    await ensureCsrfCookie();
    const payload = adminUserId !== undefined ? { admin_user_id: adminUserId } : {};
    const { data } = await apiClient.post<EraseSubjectResult>(`/api/admin/pd-subject-requests/${id}/erase`, payload);
    return data;
}
