import { db } from "@pkg/db";
import { Logger } from "@pkg/logger";
import type { Result } from "@pkg/result";
import type {
	CreateCustomerInfoPayload,
	CustomerInfoModel,
	UpdateCustomerInfoPayload,
} from "./data";
import { CustomerInfoRepository } from "./repository";

/**
 * CustomerInfoController handles business logic for customer information operations.
 * Coordinates between the repository layer and the UI/API layer.
 */
export class CustomerInfoController {
	repo: CustomerInfoRepository;

	constructor(repo: CustomerInfoRepository) {
		this.repo = repo;
	}

	/**
	 * Creates a new customer information record
	 * @param payload - Customer information data to create
	 * @returns Result containing the new customer info ID or error
	 */
	async createCustomerInfo(
		payload: CreateCustomerInfoPayload,
	): Promise<Result<number>> {
		Logger.info("Creating customer info", { email: payload.email });
		return this.repo.createCustomerInfo(payload);
	}

	/**
	 * Retrieves customer information by ID
	 * @param id - Customer info ID to retrieve
	 * @returns Result containing customer info model or error
	 */
	async getCustomerInfo(id: number): Promise<Result<CustomerInfoModel>> {
		Logger.info(`Retrieving customer info with ID: ${id}`);
		return this.repo.getCustomerInfoById(id);
	}

	/**
	 * Retrieves all customer information records
	 * @returns Result containing array of customer info models or error
	 */
	async getAllCustomerInfo(): Promise<Result<CustomerInfoModel[]>> {
		Logger.info("Retrieving all customer info records");
		return this.repo.getAllCustomerInfo();
	}

	/**
	 * Updates existing customer information
	 * @param payload - Customer information data to update (must include id)
	 * @returns Result containing success boolean or error
	 */
	async updateCustomerInfo(
		payload: UpdateCustomerInfoPayload,
	): Promise<Result<boolean>> {
		Logger.info(`Updating customer info with ID: ${payload.id}`);
		return this.repo.updateCustomerInfo(payload);
	}

	/**
	 * Deletes customer information by ID
	 * @param id - Customer info ID to delete
	 * @returns Result containing success boolean or error
	 */
	async deleteCustomerInfo(id: number): Promise<Result<boolean>> {
		Logger.info(`Deleting customer info with ID: ${id}`);
		return this.repo.deleteCustomerInfo(id);
	}
}

export function getCustomerInfoController() {
	return new CustomerInfoController(new CustomerInfoRepository(db));
}
