<?php

namespace Tests\App\Controllers\Api;

use App\Controllers\Api\SupplierController;
use App\Models\SupplierModel;
use CodeIgniter\Test\CIUnitTestCase;

class TestableSupplierController extends SupplierController
{
    public function setSupplierModel(SupplierModel $model): void
    {
        $this->supplierModel = $model;
    }
}

class SupplierControllerTest extends CIUnitTestCase
{
    private $controller;
    private $model;

    protected function setUp(): void
    {
        parent::setUp();

        $this->model = $this->createMock(SupplierModel::class);
        $this->controller = new TestableSupplierController();
        $this->controller->setSupplierModel($this->model);
    }

    public function testShowReturnsNotFound()
    {
        $this->model->method('find')->with(99)->willReturn(null);

        $response = $this->controller->show(99);
        $this->assertFalse($response['status']);
        $this->assertEquals(404, $response['code']);
    }

    public function testCreateValidSupplier()
    {
        $payload = [
            'name' => 'Campus Supplies',
            'email' => 'supplies@example.com',
        ];

        $req = $this->makeRequest('POST', '/api/v1/suppliers', $payload);
        $this->controller->setRequest($req);

        $this->model->method('insert')->with($this->arrayHasKey('name'))->willReturn(101);
        $this->model->method('find')->with(101)->willReturn(['id' => 101, 'name' => 'Campus Supplies']);

        $response = $this->controller->create();
        $this->assertTrue($response['status']);
        $this->assertEquals('Supplier created successfully', $response['message']);
        $this->assertEquals(101, $response['data']['id']);
    }

    public function testUpdateSupplierPersistsFields()
    {
        $current = ['id' => 22, 'name' => 'Old Name'];
        $this->model->method('find')->willReturnCallback(fn($id) => $current);
        $this->model->method('update')->willReturnCallback(function($id, $data) use (&$current) {
            $current = array_merge($current, $data);
            return true;
        });

        $req = $this->makeRequest('PUT', '/api/v1/suppliers/22', [
            'name' => 'New Vendor',
            'phone' => '555-0199',
        ]);
        $this->controller->setRequest($req);

        $response = $this->controller->update(22);
        $this->assertTrue($response['status']);
        $this->assertEquals('Supplier updated successfully', $response['message']);
        $this->assertEquals('New Vendor', $response['data']['name']);
    }

    public function testDeleteSupplier()
    {
        $this->model->method('find')->with(33)->willReturn(['id' => 33]);
        $this->model->method('delete')->with(33)->willReturn(true);

        $response = $this->controller->delete(33);
        $this->assertTrue($response['status']);
        $this->assertEquals('Supplier deleted successfully', $response['message']);
    }
}
