<?php

require_once BASE_PATH
    . '/app/controllers/owner/OwnerBaseController.php';

require_once BASE_PATH
    . '/app/models/Product.php';

require_once BASE_PATH
    . '/app/models/ProductCategory.php';


class OwnerProductController
    extends OwnerBaseController
{
    private Product $productModel;

    private ProductCategory $categoryModel;


    public function __construct()
    {
        $this->requireOwner();

        $this->productModel =
            new Product();

        $this->categoryModel =
            new ProductCategory();
    }


    public function index(): void
    {
        $search =
            trim(
                $_GET['search']
                ?? ''
            );


        $status =
            trim(
                $_GET['status']
                ?? ''
            );


        $allowedStatus = [
            '',
            'active',
            'hidden',
            'out_of_stock'
        ];


        if (
            !in_array(
                $status,
                $allowedStatus,
                true
            )
        ) {

            $status = '';
        }


        $page =
            max(
                1,
                (int)
                ($_GET['page'] ?? 1)
            );


        $perPage = 15;


        $totalProducts =
            $this->productModel
                ->countForOwner(
                    $search,
                    $status
                );


        $totalPages =
            max(
                1,
                (int)
                ceil(
                    $totalProducts
                    / $perPage
                )
            );


        $page =
            min(
                $page,
                $totalPages
            );


        $products =
            $this->productModel
                ->getForOwner(
                    $search,
                    $status,
                    $perPage,
                    ($page - 1)
                    * $perPage
                );


        require BASE_PATH
            . '/app/views/owner/products/index.php';
    }


    public function create(): void
    {
        $categories =
            $this->categoryModel
                ->getActiveCategories();


        require BASE_PATH
            . '/app/views/owner/products/create.php';
    }


    public function store(): void
    {
        $this->requirePost();

        $this->validateCsrf();


        try {

            $data =
                $this->validateProduct();


            $data['slug'] =
                $this->makeUniqueSlug(
                    $data['name']
                );


            $productId =
                $this->productModel
                    ->create($data);


            $uploaded =
                $this->uploadImages(
                    $productId
                );


            if (!empty($uploaded)) {

                $this->productModel
                    ->updateFeaturedImage(
                        $productId,
                        $uploaded[0]
                    );
            }


            $this->flashSuccess(
                'Đã thêm sản phẩm.'
            );


            header(
                'Location: '
                . BASE_URL
                . '/?url=owner/product/edit&id='
                . $productId
            );

            exit;

        } catch (RuntimeException $e) {

            $this->flashError(
                $e->getMessage()
            );


            $this->redirect(
                'owner/product/create'
            );
        }
    }


    public function edit(): void
    {
        $id =
            (int)
            ($_GET['id'] ?? 0);


        $product =
            $this->productModel
                ->findAnyById($id);


        if (!$product) {

            http_response_code(404);

            require BASE_PATH
                . '/app/views/errors/404.php';

            return;
        }


        $categories =
            $this->categoryModel
                ->getActiveCategories();


        $productImages =
            $this->productModel
                ->getImages($id);


        require BASE_PATH
            . '/app/views/owner/products/edit.php';
    }


    public function update(): void
    {
        $this->requirePost();

        $this->validateCsrf();


        $id =
            (int)
            ($_POST['product_id']
                ?? 0);


        $product =
            $this->productModel
                ->findAnyById($id);


        if (!$product) {

            $this->flashError(
                'Sản phẩm không tồn tại.'
            );

            $this->redirect(
                'owner/products'
            );
        }


        try {

            $data =
                $this->validateProduct(
                    $id
                );


            $data['slug'] =
                $this->makeUniqueSlug(
                    $data['name'],
                    $id
                );


            $this->productModel
                ->updateProduct(
                    $id,
                    $data
                );


            $uploaded =
                $this->uploadImages(
                    $id
                );


            if (
                empty(
                    $product[
                        'featured_image'
                    ]
                )

                && !empty($uploaded)
            ) {

                $this->productModel
                    ->updateFeaturedImage(
                        $id,
                        $uploaded[0]
                    );
            }


            $this->flashSuccess(
                'Đã cập nhật sản phẩm.'
            );

        } catch (RuntimeException $e) {

            $this->flashError(
                $e->getMessage()
            );
        }


        header(
            'Location: '
            . BASE_URL
            . '/?url=owner/product/edit&id='
            . $id
        );

        exit;
    }


    public function hide(): void
    {
        $this->requirePost();

        $this->validateCsrf();


        $id =
            (int)
            ($_POST['product_id']
                ?? 0);


        $this->productModel
            ->updateStatus(
                $id,
                'hidden'
            );


        $this->flashSuccess(
            'Đã ẩn sản phẩm.'
        );


        $this->redirect(
            'owner/products'
        );
    }


    public function deleteImage(): void
{
    $this->requirePost();

    $this->validateCsrf();


    $productId =
        (int)
        ($_POST['product_id'] ?? 0);


    $imageId =
        (int)
        ($_POST['image_id'] ?? 0);


    $product =
        $this->productModel
            ->findAnyById(
                $productId
            );


    if (!$product) {

        $this->flashError(
            'Sản phẩm không tồn tại.'
        );

        $this->redirect(
            'owner/products'
        );
    }


    $image =
        $this->productModel
            ->findImageById(
                $imageId,
                $productId
            );


    if (!$image) {

        $this->flashError(
            'Ảnh không tồn tại.'
        );

        header(
            'Location: '
            . BASE_URL
            . '/?url=owner/product/edit&id='
            . $productId
        );

        exit;
    }


    $isFeatured =
        !empty(
            $product['featured_image']
        )

        && $product['featured_image']
        === $image['image_path'];


    // Lấy ảnh thay thế trước khi xóa
    $nextImage =
        $this->productModel
            ->getFirstImage(
                $productId,
                $imageId
            );


    // Xóa file
    $filePath =
        BASE_PATH
        . '/public/'
        . ltrim(
            $image['image_path'],
            '/'
        );


    if (is_file($filePath)) {

        @unlink($filePath);
    }


    // Xóa DB
    $this->productModel
        ->deleteImage(
            $imageId,
            $productId
        );


    // Nếu ảnh vừa xóa là featured
    if ($isFeatured) {

        if ($nextImage) {

            $this->productModel
                ->setFeaturedImage(
                    $productId,
                    $nextImage['image_path']
                );

        } else {

            $this->productModel
                ->clearFeaturedImage(
                    $productId
                );
        }
    }


    $this->flashSuccess(
        'Đã xóa ảnh sản phẩm.'
    );


    header(
        'Location: '
        . BASE_URL
        . '/?url=owner/product/edit&id='
        . $productId
    );

    exit;
}


    private function validateProduct(
        ?int $excludeId = null
    ): array {

        $name =
            trim(
                $_POST['name']
                ?? ''
            );


        $sku =
            strtoupper(
                trim(
                    $_POST['sku']
                    ?? ''
                )
            );


        $categoryId =
            (int)
            ($_POST['category_id']
                ?? 0);


        $price =
            (float)
            ($_POST['price']
                ?? 0);


        $salePriceRaw =
            trim(
                $_POST['sale_price']
                ?? ''
            );


        $salePrice =
            $salePriceRaw !== ''
                ? (float)
                    $salePriceRaw
                : null;


        $stock =
            max(
                0,
                (int)
                ($_POST[
                    'stock_quantity'
                ] ?? 0)
            );


        if ($name === '') {

            throw new RuntimeException(
                'Tên sản phẩm không được để trống.'
            );
        }


        $category =
            $this->categoryModel
                ->findById(
                    $categoryId
                );


        if (!$category) {

            throw new RuntimeException(
                'Danh mục sản phẩm không hợp lệ.'
            );
        }


        if ($price <= 0) {

            throw new RuntimeException(
                'Giá bán phải lớn hơn 0.'
            );
        }


        if (
            $salePrice !== null
            && (
                $salePrice < 0
                || $salePrice >= $price
            )
        ) {

            throw new RuntimeException(
                'Giá khuyến mãi phải nhỏ hơn giá gốc.'
            );
        }


        if (
            $sku !== ''
            && $this->productModel
                ->skuExists(
                    $sku,
                    $excludeId
                )
        ) {

            throw new RuntimeException(
                'SKU đã tồn tại.'
            );
        }


        $petTarget =
            $_POST['pet_target']
            ?? 'all';


        if (
            !in_array(
                $petTarget,
                [
                    'dog',
                    'cat',
                    'all'
                ],
                true
            )
        ) {

            $petTarget =
                'all';
        }


        $status =
            $_POST['status']
            ?? 'active';


        if (
            !in_array(
                $status,
                [
                    'active',
                    'hidden',
                    'out_of_stock'
                ],
                true
            )
        ) {

            $status =
                'active';
        }


        if ($status !== 'hidden') {

            $status = $stock === 0
                ? 'out_of_stock'
                : 'active';
        }


        return [

            'category_id' =>
                $categoryId,

            'sku' =>
                $sku,

            'name' =>
                $name,

            'short_description' =>
                trim(
                    $_POST[
                        'short_description'
                    ]
                    ?? ''
                ),

            'description' =>
                trim(
                    $_POST['description']
                    ?? ''
                ),

            'brand' =>
                trim(
                    $_POST['brand']
                    ?? ''
                ),

            'pet_target' =>
                $petTarget,

            'price' =>
                $price,

            'sale_price' =>
                $salePrice,

            'stock_quantity' =>
                $stock,

            'status' =>
                $status,

            'is_featured' =>
                isset(
                    $_POST[
                        'is_featured'
                    ]
                )
                    ? 1
                    : 0
        ];
    }


    private function uploadImages(
        int $productId
    ): array {

        if (
            empty(
                $_FILES[
                    'product_images'
                ]
            )
        ) {

            return [];
        }


        $files =
            $_FILES[
                'product_images'
            ];


        $uploadDir =
            BASE_PATH
            . '/public/uploads/products/';


        if (
            !is_dir(
                $uploadDir
            )
        ) {

            mkdir(
                $uploadDir,
                0755,
                true
            );
        }


        $allowedMime = [

            'image/jpeg' =>
                'jpg',

            'image/png' =>
                'png',

            'image/webp' =>
                'webp'
        ];


        $uploaded = [];


        $finfo =
            new finfo(
                FILEINFO_MIME_TYPE
            );


        foreach (
            $files['tmp_name']
            as $index => $tmpName
        ) {

            if (
                $files['error'][$index]
                === UPLOAD_ERR_NO_FILE
            ) {

                continue;
            }


            if (
                $files['error'][$index]
                !== UPLOAD_ERR_OK
            ) {

                throw new RuntimeException(
                    'Có lỗi khi upload ảnh.'
                );
            }


            if (
                $files['size'][$index]
                > 5 * 1024 * 1024
            ) {

                throw new RuntimeException(
                    'Mỗi ảnh tối đa 5MB.'
                );
            }


            $mime =
                $finfo->file(
                    $tmpName
                );


            if (
                !isset(
                    $allowedMime[$mime]
                )
            ) {

                throw new RuntimeException(
                    'Chỉ chấp nhận JPG, PNG hoặc WEBP.'
                );
            }


            $extension =
                $allowedMime[$mime];


            $filename =
                'product_'
                . $productId
                . '_'
                . bin2hex(
                    random_bytes(8)
                )
                . '.'
                . $extension;


            $destination =
                $uploadDir
                . $filename;


            if (
                !move_uploaded_file(
                    $tmpName,
                    $destination
                )
            ) {

                throw new RuntimeException(
                    'Không thể lưu ảnh sản phẩm.'
                );
            }


            $relativePath =
                'uploads/products/'
                . $filename;


            $this->productModel
                ->addImage(
                    $productId,
                    $relativePath,
                    $index
                );


            $uploaded[] =
                $relativePath;
        }


        return $uploaded;
    }


    private function makeUniqueSlug(
        string $name,
        ?int $excludeId = null
    ): string {

        $slug =
            $this->slugify(
                $name
            );


        if ($slug === '') {

            $slug =
                'product';
        }


        $baseSlug =
            $slug;

        $number = 2;


        while (
            $this->productModel
                ->slugExists(
                    $slug,
                    $excludeId
                )
        ) {

            $slug =
                $baseSlug
                . '-'
                . $number;

            $number++;
        }


        return $slug;
    }


    private function slugify(
        string $text
    ): string {

        $text =
            str_replace(
                ['Đ', 'đ'],
                ['D', 'd'],
                $text
            );


        $converted =
            iconv(
                'UTF-8',
                'ASCII//TRANSLIT//IGNORE',
                $text
            );


        if (
            $converted !== false
        ) {

            $text =
                $converted;
        }


        $text =
            strtolower(
                $text
            );


        $text =
            preg_replace(
                '/[^a-z0-9]+/',
                '-',
                $text
            );


        return trim(
            $text,
            '-'
        );
    }
}
