import {
    CLIENT_ACCOUNT_MOVEMENT_STATUS,
    CLIENT_ACCOUNT_PAYMENT_METHODS,
} from "../ClientAccountMovements/ClientAccountMovements.Interface";
import { IPaymentDocument } from "./Payments.Adapter.Mongoose";

export enum PAYMENT_METHODS_CLIENT_ACCOUNT {
    CLIENT_ACCOUNT = "ACCOUNT",
}

export type PAYMENT_METHODS = CLIENT_ACCOUNT_PAYMENT_METHODS | PAYMENT_METHODS_CLIENT_ACCOUNT;

export type FindPaymentsParams = {
    id?: string;
    clientId?: string;
    clientIds?: string[];
    companyId?: string;
    appointmentId?: string;
    employeeId?: string;
    serviceId?: string;
    status?: CLIENT_ACCOUNT_MOVEMENT_STATUS;
    method?: PAYMENT_METHODS;
    startDate?: Date;
    endDate?: Date;
    proccessDate?: PAYMENT_PROCCESS_DATE;
    sessionUser?: string;
};

export type PaginatePaymentsParams = FindPaymentsParams & {
    page: number;
    limit: number;
};

export type PaginatePaymentsResults = {
    data: IPayment[];
    page: number;
    pages: number;
};

export enum PAYMENT_PROCCESS_DATE {
    NOW = "now",
    APPOINTMENT = "appointment",
}

export type CreatePaymentParams = {
    amount: number;
    method: PAYMENT_METHODS;
    status: CLIENT_ACCOUNT_MOVEMENT_STATUS;
    appointmentId: string;
    description?: string;
    proccessDate: PAYMENT_PROCCESS_DATE;
    sessionUser?: string;
};

export type CreatePaymentExtraParams = CreatePaymentParams & {
    clientId: string;
    companyId: string;
    employeeId: string;
    serviceId: string;
};

export type DeletePaymentParams = {
    id: string;
    sessionUser?: string;
};

export type GetAppointmentPaymentsParams = {
    appointmentId: string;
    sessionUser?: string;
};

export type MarkAsPayedParams = {
    appointmentId: string;
    method: PAYMENT_METHODS;
    sessionUser?: string;
};

export interface PaginatePaymentsView {
    id: string;
    appointmentId: string;
    appointmentDate: Date;
    clientId: string;
    clientName: string;
    employeeId: string;
    employeeName: string;
    serviceId: string;
    serviceName: string;
    price: number;
    status: CLIENT_ACCOUNT_MOVEMENT_STATUS;
    method: PAYMENT_METHODS;
    description: string;
    createdAt: Date;
}

export type PaginateNotPayedAppointmentsParams = FindPaymentsParams & {
    page: number;
    limit: number;
};

export type PaginateNotPayedAppointmentsResult = {
    data: PaginatePaymentsView[];
    page: number;
    pages: number;
};

export type PaginatePaymentsViewParams = FindPaymentsParams & {
    page: number;
    limit: number;
};

export type PaginatePaymentsViewResults = {
    data: PaginatePaymentsView[];
    page: number;
    pages: number;
};

export type DeletePaymentsByCompanyParams = {
    companyId: string;
};

export type DeletePaymentsByClientParams = {
    clientId: string;
};

export interface IPayment {
    id?: string;
    _id?: string;
    amount: number;
    status: CLIENT_ACCOUNT_MOVEMENT_STATUS;
    method: PAYMENT_METHODS;
    clientId: string;
    companyId: string;
    employeeId: string;
    serviceId: string;
    appointmentId: string;
    description: string;
    createdAt: Date;
    updatedAt: Date;
}

export interface IPaymentsAdapter {
    create(data: CreatePaymentExtraParams): Promise<IPayment>;
    delete(id: string): Promise<void>;
    find(filters: FindPaymentsParams): Promise<IPayment[]>;
    findOne(filters: FindPaymentsParams): Promise<IPaymentDocument | null>;
    paginate(filters: PaginatePaymentsParams): Promise<PaginatePaymentsResults>;
}


export type NotPayedReportResult = {
    items: PaginatePaymentsView[];
    totalAmount: number;
};

export type PaymentsReportResult = {
    items: PaginatePaymentsView[];
    totalAmount: number;
};

export interface IPaymentsManager {
    payments: IPaymentsAdapter;
    createPayment(data: CreatePaymentParams): Promise<IPayment>;
    getAppointmentPayments(datas: GetAppointmentPaymentsParams): Promise<IPayment[]>;
    deletePayment(data: DeletePaymentParams): Promise<void>;
    deletePaymentsByCompany(data: DeletePaymentsByCompanyParams): Promise<void>;
    deletePaymentsByClient(data: DeletePaymentsByClientParams): Promise<void>;
    markAsPayed(data: MarkAsPayedParams): Promise<void>;
    paginatePaymentsView(data: PaginatePaymentsViewParams): Promise<PaginatePaymentsViewResults>;
    paginatedPaymentsViewTotal(data: FindPaymentsParams): Promise<number>;
    paginateNotPayedAppointments(
        data: PaginateNotPayedAppointmentsParams
    ): Promise<PaginateNotPayedAppointmentsResult>;

    paginatedNotPayedAppiontmentsTotal(data: FindPaymentsParams): Promise<number>;
    payNotPayedAppointments(data: FindPaymentsParams): Promise<void>;
    getNotPayedReport(data: FindPaymentsParams): Promise<NotPayedReportResult>;
    getPaymentsReport(data: FindPaymentsParams): Promise<PaymentsReportResult>;
}
