import { describe, it, expect, vi } from 'vitest';
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithProviders } from '../../test/utils';

vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));

import ResourceServicesPanel from './ResourceServicesPanel';

const resource = { uuid: 'r-1', name: 'دستگاه شمارهٔ ۲' } as never;

/** PriceInput مبلغ را با جداکنندهٔ fa-IR نشان می‌دهد، نه رقمِ خام. */
const fa = (n: number) => new Intl.NumberFormat('fa-IR').format(n);

const services = [
  { uuid: 's-1', name: 'لیزر پا', duration_minutes: 30, price_rials: 8_000_000 },
  { uuid: 's-2', name: 'لیزر دست', duration_minutes: 20, price_rials: 5_000_000 },
];

/** ردیفی که مدتش را خودِ منبع گفته ولی قیمتش را از سرویس ارث برده. */
const offerings = [
  {
    service_uuid: 's-1',
    service_name: 'لیزر پا',
    duration_minutes: 15,
    price_rials: null,
    active: true,
    effective_duration_minutes: 15,
    effective_price_rials: 8_000_000,
    duration_source: 'resource_option',
    price_source: 'service_default',
  },
];

function props(overrides: Record<string, unknown> = {}) {
  return {
    resource,
    offerings: offerings as never,
    services: services as never,
    saving: false,
    onCancel: vi.fn(),
    onSave: vi.fn(),
    ...overrides,
  };
}

/**
 * پنل مستقیماً تست می‌شود، نه از راه مودال: مودالِ فهرست منابع حذف شد چون همان کار
 * را تبِ «سرویس‌ها»ی خودِ منبع می‌کند. منطقِ ارث‌بری/override همان است و باید بماند.
 */
describe('ResourceServicesPanel', () => {
  it('نشان می‌دهد مقدار ارث‌بری‌شده از کجا آمده', () => {
    renderWithProviders(<ResourceServicesPanel {...props()} />);

    // مدت را خودِ منبع گفته، پس در خانه است.
    expect(screen.getByDisplayValue('15')).toBeInTheDocument();

    // قیمت تنظیم نشده: خانه خالی است و مقدار مؤثر با برچسبِ منبعش در placeholder.
    const price = screen.getByPlaceholderText(/پیش‌فرض سرویس/);
    expect(price).toHaveValue('');
  });

  it('قیمت به تومان گرفته می‌شود و به ریال ذخیره می‌شود', async () => {
    const onSave = vi.fn();
    renderWithProviders(<ResourceServicesPanel {...props({ onSave })} />);

    // برچسب و placeholder هر دو تومان‌اند؛ پیش از این برچسب «ریال» بود و ورودی
    // کاربر ده برابر کمتر از چیزی می‌شد که فکر می‌کرد وارد کرده.
    expect(screen.getByText('قیمت (تومان)')).toBeInTheDocument();
    expect(screen.queryByText('قیمت (ریال)')).not.toBeInTheDocument();

    const price = screen.getByPlaceholderText(/پیش‌فرض سرویس/);
    await userEvent.type(price, '950000');
    await userEvent.click(screen.getByRole('button', { name: 'ذخیره' }));

    expect(onSave).toHaveBeenCalledWith([
      { service_uuid: 's-1', duration_minutes: '15', price_rials: '9500000', active: true },
    ]);
  });

  it('قیمتِ override شده به تومان در فیلد می‌نشیند', () => {
    renderWithProviders(<ResourceServicesPanel {...props({
      offerings: [{ ...offerings[0], price_rials: 9_500_000, price_source: 'resource_option' }] as never,
    })} />);

    expect(screen.getByDisplayValue(fa(950_000))).toBeInTheDocument();
  });

  it('سرویس تازه با مدت و قیمت پیش‌فرض خودش پر می‌شود', async () => {
    const onSave = vi.fn();
    renderWithProviders(<ResourceServicesPanel {...props({ onSave })} />);

    await userEvent.click(screen.getByText('یک سرویس انتخاب کنید'));
    await userEvent.click(await screen.findByText('لیزر دست'));

    // ۵٬۰۰۰٬۰۰۰ ریال = ۵۰۰٬۰۰۰ تومان
    expect(screen.getByDisplayValue(fa(500_000))).toBeInTheDocument();
    expect(screen.getByDisplayValue('20')).toBeInTheDocument();

    await userEvent.click(screen.getByRole('button', { name: 'ذخیره' }));

    expect(onSave).toHaveBeenCalledWith([
      { service_uuid: 's-1', duration_minutes: '15', price_rials: '', active: true },
      { service_uuid: 's-2', duration_minutes: '20', price_rials: '5000000', active: true },
    ]);
  });

  it('پاک‌کردن مقدار یعنی بازگشت به ارث، نه صفر', async () => {
    const onSave = vi.fn();
    renderWithProviders(<ResourceServicesPanel {...props({ onSave })} />);

    await userEvent.clear(screen.getByDisplayValue('15'));
    await userEvent.click(screen.getByRole('button', { name: 'ذخیره' }));

    // رشتهٔ خالی به سرور می‌رود و سرور آن را `null` می‌فهمد — نه `0`.
    expect(onSave).toHaveBeenCalledWith([
      { service_uuid: 's-1', duration_minutes: '', price_rials: '', active: true },
    ]);
  });
});
