<?php
/**
 * CSV export functionality.
 *
 * @package MerchantKits\AttendanceManager
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Builds and streams CSV exports for employees, attendance, and leaves.
 */
class MKAM_Export {

	/**
	 * AJAX entry point for exports triggered from admin tables.
	 *
	 * @return void
	 */
	public function ajax_export() {
		check_admin_referer( 'mkam_export' );

		if ( ! current_user_can( MKAM_Core::admin_capability() ) ) {
			wp_die( esc_html__( 'Permission denied.', 'merchantkits-attendance-manager' ) );
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$type = isset( $_REQUEST['export_type'] ) ? sanitize_key( wp_unslash( $_REQUEST['export_type'] ) ) : '';

		switch ( $type ) {
			case 'employees':
				$this->employees_csv();
				break;
			case 'attendance':
				$this->attendance_csv( $this->request_filters() );
				break;
			case 'leaves':
				$this->leaves_csv( $this->request_filters() );
				break;
			default:
				wp_die( esc_html__( 'Unknown export type.', 'merchantkits-attendance-manager' ) );
		}
	}

	/**
	 * Collect common filters from the request.
	 *
	 * @return array
	 */
	private function request_filters() {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		return array(
			'date_from'   => isset( $_REQUEST['date_from'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['date_from'] ) ) : '',
			'date_to'     => isset( $_REQUEST['date_to'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['date_to'] ) ) : '',
			'status'      => isset( $_REQUEST['status'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['status'] ) ) : '',
			'employee_id' => isset( $_REQUEST['employee_id'] ) ? absint( $_REQUEST['employee_id'] ) : 0,
		);
		// phpcs:enable WordPress.Security.NonceVerification.Recommended
	}

	/**
	 * Send CSV download headers.
	 *
	 * @param string $filename Suggested filename.
	 * @return void
	 */
	private function send_headers( $filename ) {
		nocache_headers();
		header( 'Content-Type: text/csv; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename="' . sanitize_file_name( $filename ) . '"' );
	}

	/**
	 * Write rows to php://output and exit.
	 *
	 * @param array $header Column headers.
	 * @param array $rows   Array of row arrays.
	 * @return void
	 */
	private function output( $header, $rows ) {
		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
		$fh = fopen( 'php://output', 'w' );

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fputcsv
		fputcsv( $fh, $header );

		foreach ( $rows as $row ) {
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fputcsv
			fputcsv( $fh, $row );
		}

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
		fclose( $fh );
		exit;
	}

	/**
	 * Export employees as CSV.
	 *
	 * @param array $ids Optional employee IDs to limit the export.
	 * @return void
	 */
	public function employees_csv( $ids = array() ) {
		$this->send_headers( 'employees-export-' . gmdate( 'Y-m-d' ) . '.csv' );

		$header = apply_filters(
			'mkam_export_columns',
			array(
				__( 'Employee ID', 'merchantkits-attendance-manager' ),
				__( 'First Name', 'merchantkits-attendance-manager' ),
				__( 'Last Name', 'merchantkits-attendance-manager' ),
				__( 'Email', 'merchantkits-attendance-manager' ),
				__( 'Phone', 'merchantkits-attendance-manager' ),
				__( 'Department', 'merchantkits-attendance-manager' ),
				__( 'Designation', 'merchantkits-attendance-manager' ),
				__( 'Employment Type', 'merchantkits-attendance-manager' ),
				__( 'Status', 'merchantkits-attendance-manager' ),
				__( 'Join Date', 'merchantkits-attendance-manager' ),
			),
			'employees'
		);

		$employees = MKAM_Employee::query( array() );
		$rows      = array();

		foreach ( $employees as $employee ) {
			if ( ! empty( $ids ) && ! in_array( (int) $employee['id'], array_map( 'intval', $ids ), true ) ) {
				continue;
			}

			$rows[] = apply_filters(
				'mkam_export_row',
				array(
					$employee['employee_id'],
					$employee['first_name'],
					$employee['last_name'],
					$employee['email'],
					$employee['phone'],
					$employee['department'],
					$employee['designation'],
					$employee['employment_type'],
					$employee['status'],
					$employee['join_date'],
				),
				'employees'
			);
		}

		$this->output( $header, $rows );
	}

	/**
	 * Export attendance records as CSV.
	 *
	 * @param array $filters Date/status/employee filters or 'ids'.
	 * @return void
	 */
	public function attendance_csv( $filters = array() ) {
		$this->send_headers( 'attendance-export-' . gmdate( 'Y-m-d' ) . '.csv' );

		$header = apply_filters(
			'mkam_export_columns',
			array(
				__( 'Employee', 'merchantkits-attendance-manager' ),
				__( 'Date', 'merchantkits-attendance-manager' ),
				__( 'Clock In', 'merchantkits-attendance-manager' ),
				__( 'Clock Out', 'merchantkits-attendance-manager' ),
				__( 'Total Hours', 'merchantkits-attendance-manager' ),
				__( 'Overtime', 'merchantkits-attendance-manager' ),
				__( 'Status', 'merchantkits-attendance-manager' ),
				__( 'Late Minutes', 'merchantkits-attendance-manager' ),
			),
			'attendance'
		);

		$records = MKAM_Attendance::query(
			array(
				'employee_id' => isset( $filters['employee_id'] ) ? absint( $filters['employee_id'] ) : 0,
				'status'      => isset( $filters['status'] ) ? $filters['status'] : '',
				'date_from'   => isset( $filters['date_from'] ) ? $filters['date_from'] : '',
				'date_to'     => isset( $filters['date_to'] ) ? $filters['date_to'] : '',
			)
		);

		$ids  = isset( $filters['ids'] ) ? array_map( 'intval', (array) $filters['ids'] ) : array();
		$rows = array();

		foreach ( $records as $record ) {
			if ( ! empty( $ids ) && ! in_array( (int) $record['id'], $ids, true ) ) {
				continue;
			}

			$employee = MKAM_Employee::get( $record['employee_id'] );

			$rows[] = apply_filters(
				'mkam_export_row',
				array(
					$employee ? MKAM_Employee::full_name( $employee ) : (string) $record['employee_id'],
					$record['date'],
					$record['clock_in'],
					$record['clock_out'],
					$record['total_hours'],
					$record['overtime_hours'],
					$record['status'],
					$record['late_minutes'],
				),
				'attendance'
			);
		}

		$this->output( $header, $rows );
	}

	/**
	 * Export leave records as CSV.
	 *
	 * @param array $filters Filters or 'ids'.
	 * @return void
	 */
	public function leaves_csv( $filters = array() ) {
		$this->send_headers( 'leaves-export-' . gmdate( 'Y-m-d' ) . '.csv' );

		$header = apply_filters(
			'mkam_export_columns',
			array(
				__( 'Employee', 'merchantkits-attendance-manager' ),
				__( 'Leave Type', 'merchantkits-attendance-manager' ),
				__( 'From', 'merchantkits-attendance-manager' ),
				__( 'To', 'merchantkits-attendance-manager' ),
				__( 'Days', 'merchantkits-attendance-manager' ),
				__( 'Status', 'merchantkits-attendance-manager' ),
				__( 'Applied On', 'merchantkits-attendance-manager' ),
			),
			'leaves'
		);

		$leaves = MKAM_Leave::query(
			array(
				'employee_id' => isset( $filters['employee_id'] ) ? absint( $filters['employee_id'] ) : 0,
				'status'      => isset( $filters['status'] ) ? $filters['status'] : '',
			)
		);

		$ids  = isset( $filters['ids'] ) ? array_map( 'intval', (array) $filters['ids'] ) : array();
		$rows = array();

		foreach ( $leaves as $leave ) {
			if ( ! empty( $ids ) && ! in_array( (int) $leave['id'], $ids, true ) ) {
				continue;
			}

			$employee = MKAM_Employee::get( $leave['employee_id'] );
			$policy   = MKAM_Leave::get_policy( $leave['leave_type'] );

			$rows[] = apply_filters(
				'mkam_export_row',
				array(
					$employee ? MKAM_Employee::full_name( $employee ) : (string) $leave['employee_id'],
					$policy ? $policy['label'] : $leave['leave_type'],
					$leave['start_date'],
					$leave['end_date'],
					$leave['total_days'],
					$leave['status'],
					$leave['created_at'],
				),
				'leaves'
			);
		}

		$this->output( $header, $rows );
	}
}
