<?php

namespace Tests\Feature;

use App\Mail\ShopOrderConfirmationMail;
use App\Mail\ShopPasswordResetMail;
use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Models\Tenant\OnlineOrder;
use App\Models\Tenant\ShopCustomer;
use App\Services\Notifications\ShopOrderNotifier;
use App\Services\Notifications\TelegramService;
use App\Services\Notifications\WebPushService;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Password;
use Tests\TestCase;

class ShopPasswordResetTest extends TestCase
{
    use RefreshDatabase;

    public function test_forgot_password_sends_reset_mail(): void
    {
        $this->makeShop('pr');
        ShopCustomer::create([
            'name' => 'X', 'phone' => '+37377000001',
            'email' => 'x@example.com', 'password' => Hash::make('old'),
        ]);

        Mail::fake();

        $this->post('http://pr.service.mir.md/shop/password/email', [
            'email' => 'x@example.com',
        ])->assertSessionHas('status');

        Mail::assertSent(ShopPasswordResetMail::class, fn ($m) => $m->customer->email === 'x@example.com');
    }

    public function test_forgot_does_not_disclose_unknown_email(): void
    {
        $this->makeShop('pru');
        Mail::fake();

        $this->post('http://pru.service.mir.md/shop/password/email', [
            'email' => 'ghost@example.com',
        ])->assertSessionHas('status'); // same generic status, no error

        Mail::assertNothingSent();
    }

    public function test_reset_with_valid_token_changes_password(): void
    {
        $this->makeShop('rs');
        $cust = ShopCustomer::create([
            'name' => 'R', 'phone' => '+37377000002',
            'email' => 'r@example.com', 'password' => Hash::make('old'),
        ]);

        $token = Password::broker('shop_customers')->createToken($cust);

        $this->post('http://rs.service.mir.md/shop/password/reset', [
            'token' => $token,
            'email' => 'r@example.com',
            'password' => 'newpassword',
            'password_confirmation' => 'newpassword',
        ])->assertRedirect('/shop/login');

        $cust->refresh();
        $this->assertTrue(Hash::check('newpassword', $cust->password));
    }

    public function test_reset_with_bad_token_rejected(): void
    {
        $this->makeShop('bad');
        ShopCustomer::create([
            'name' => 'B', 'phone' => '+37377000003',
            'email' => 'b@example.com', 'password' => Hash::make('old'),
        ]);

        $this->post('http://bad.service.mir.md/shop/password/reset', [
            'token' => 'not-a-real-token',
            'email' => 'b@example.com',
            'password' => 'newpassword',
            'password_confirmation' => 'newpassword',
        ])->assertSessionHasErrors();
    }

    public function test_order_notifier_sends_email_when_customer_email_present(): void
    {
        $ctx = $this->makeShop('mail');

        Mail::fake();
        $order = OnlineOrder::create([
            'number' => OnlineOrder::generateNumber($ctx->id),
            'customer_name' => 'M', 'customer_phone' => '+37377000004',
            'customer_email' => 'm@example.com',
            'delivery_method' => 'pickup', 'status' => 'new',
        ]);

        app(ShopOrderNotifier::class)->placed($order);

        Mail::assertSent(ShopOrderConfirmationMail::class, fn ($m) => $m->order->id === $order->id);
    }

    public function test_order_notifier_skips_email_without_customer_email(): void
    {
        $ctx = $this->makeShop('noeml');
        Mail::fake();
        $order = OnlineOrder::create([
            'number' => OnlineOrder::generateNumber($ctx->id),
            'customer_name' => 'N', 'customer_phone' => '+37377000005',
            'delivery_method' => 'pickup', 'status' => 'new',
        ]);
        app(ShopOrderNotifier::class)->placed($order);
        Mail::assertNotSent(ShopOrderConfirmationMail::class);
    }

    public function test_part_has_multiple_images_collection(): void
    {
        $this->makeShop('multi');
        $part = \App\Models\Tenant\Part::create([
            'name' => 'P', 'sell_price' => 10, 'qty' => 1,
            'unit' => 'buc', 'is_active' => true, 'buy_price' => 5,
        ]);
        $this->assertIsArray($part->imageUrls());
        $this->assertCount(0, $part->imageUrls());
    }

    private function makeShop(string $slug): Company
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id, 'slug' => $slug,
            'name' => ucfirst($slug), 'status' => 'active',
            'settings' => ['shop' => ['enabled' => true, 'delivery_methods' => ['pickup']]],
        ]);
        app(TenantManager::class)->setCurrent($company);
        return $company;
    }
}
