<?php

declare(strict_types=1);

namespace BadamSoft\WooProductExporter\Exporter\Formats;

use BadamSoft\WooProductExporter\Exporter\Formats\Contracts\WriterInterface;
use BadamSoft\WooProductExporter\Helpers\DownloadHelper;

abstract class AbstractStreamWriter implements WriterInterface {
    /**
     * @var resource|null
     */
    protected $handle;

    /**
     * @var array<string, array<string, mixed>>
     */
    protected array $field_definitions = [];

    /**
     * @var array<int, string>
     */
    protected array $fields = [];

    /**
     * @var string 'browser'|'file'
     */
    protected string $destination = 'browser';

    protected ?string $file_path = null;

    protected function open_stream( string $filename, string $content_type, array $settings = [], bool $with_bom = false ): void {
        $destination = $settings['_destination'] ?? 'browser';

        if ( 'file' === $destination ) {
            $file_path = $settings['_file_path'] ?? '';

            $this->handle = $file_path ? fopen( $file_path, 'wb' ) : false; // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen

            if ( false === $this->handle ) {
                wp_die( esc_html__( 'Could not open export file for writing.', 'badamsoft-product-exporter-for-woocommerce' ) );
            }

            $this->destination = 'file';
            $this->file_path   = $file_path;

            if ( $with_bom ) {
                DownloadHelper::emit_bom( $this->handle );
            }

            return;
        }

        $this->destination = 'browser';
        $this->file_path   = null;

        DownloadHelper::send_headers( $filename, $content_type );

        $this->handle = fopen( 'php://output', 'wb' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen

        if ( false === $this->handle ) {
            wp_die( esc_html__( 'Could not open output stream.', 'badamsoft-product-exporter-for-woocommerce' ) );
        }

        if ( $with_bom ) {
            DownloadHelper::emit_bom( $this->handle );
        }
    }

    protected function open_output_stream( string $filename, string $content_type, bool $with_bom = false ): void {
        $this->open_stream( $filename, $content_type, [], $with_bom );
    }

    protected function close_stream(): void {
        if ( is_resource( $this->handle ) ) {
            fclose( $this->handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
        }
    }

    protected function close_output_stream(): void {
        $this->close_stream();
    }

    protected function is_file_destination(): bool {
        return 'file' === $this->destination && ! empty( $this->file_path );
    }

    public function get_file_path(): ?string {
        return $this->file_path;
    }
}
