package mappers

import (
	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/models"
	"time"
)

// Chart of Account Type Mappers
func ContractToModelCreateChartOfAccountTypeRequest(req *contract.CreateChartOfAccountTypeRequest) *models.CreateChartOfAccountTypeRequest {
	return &models.CreateChartOfAccountTypeRequest{
		Name:        req.Name,
		Code:        req.Code,
		Description: req.Description,
	}
}

func ContractToModelUpdateChartOfAccountTypeRequest(req *contract.UpdateChartOfAccountTypeRequest) *models.UpdateChartOfAccountTypeRequest {
	return &models.UpdateChartOfAccountTypeRequest{
		Name:        req.Name,
		Code:        req.Code,
		Description: req.Description,
		IsActive:    req.IsActive,
	}
}

func ModelToContractChartOfAccountTypeResponse(resp *models.ChartOfAccountTypeResponse) *contract.ChartOfAccountTypeResponse {
	return &contract.ChartOfAccountTypeResponse{
		ID:          resp.ID,
		Name:        resp.Name,
		Code:        resp.Code,
		Description: resp.Description,
		IsActive:    resp.IsActive,
		CreatedAt:   resp.CreatedAt.Format(time.RFC3339),
		UpdatedAt:   resp.UpdatedAt.Format(time.RFC3339),
	}
}

// Chart of Account Mappers
func ContractToModelCreateChartOfAccountRequest(req *contract.CreateChartOfAccountRequest) *models.CreateChartOfAccountRequest {
	return &models.CreateChartOfAccountRequest{
		ChartOfAccountTypeID: req.ChartOfAccountTypeID,
		ParentID:             req.ParentID,
		Name:                 req.Name,
		Code:                 req.Code,
		Description:          req.Description,
	}
}

func ContractToModelUpdateChartOfAccountRequest(req *contract.UpdateChartOfAccountRequest) *models.UpdateChartOfAccountRequest {
	return &models.UpdateChartOfAccountRequest{
		ChartOfAccountTypeID: req.ChartOfAccountTypeID,
		ParentID:             req.ParentID,
		Name:                 req.Name,
		Code:                 req.Code,
		Description:          req.Description,
		IsActive:             req.IsActive,
	}
}

func ContractToModelListChartOfAccountsRequest(req *contract.ListChartOfAccountsRequest) *models.ListChartOfAccountsRequest {
	return &models.ListChartOfAccountsRequest{
		OrganizationID:       req.OrganizationID,
		OutletID:             req.OutletID,
		ChartOfAccountTypeID: req.ChartOfAccountTypeID,
		ParentID:             req.ParentID,
		IsActive:             req.IsActive,
		IsSystem:             req.IsSystem,
		Page:                 req.Page,
		Limit:                req.Limit,
	}
}

func ModelToContractChartOfAccountResponse(resp *models.ChartOfAccountResponse) *contract.ChartOfAccountResponse {
	contractResp := &contract.ChartOfAccountResponse{
		ID:                   resp.ID,
		OrganizationID:       resp.OrganizationID,
		OutletID:             resp.OutletID,
		ChartOfAccountTypeID: resp.ChartOfAccountTypeID,
		ParentID:             resp.ParentID,
		Name:                 resp.Name,
		Code:                 resp.Code,
		Description:          resp.Description,
		IsActive:             resp.IsActive,
		IsSystem:             resp.IsSystem,
		CreatedAt:            resp.CreatedAt.Format(time.RFC3339),
		UpdatedAt:            resp.UpdatedAt.Format(time.RFC3339),
	}

	if resp.ChartOfAccountType != nil {
		contractResp.ChartOfAccountType = ModelToContractChartOfAccountTypeResponse(resp.ChartOfAccountType)
	}

	if resp.Parent != nil {
		contractResp.Parent = ModelToContractChartOfAccountResponse(resp.Parent)
	}

	if len(resp.Children) > 0 {
		contractResp.Children = make([]contract.ChartOfAccountResponse, len(resp.Children))
		for i, child := range resp.Children {
			contractResp.Children[i] = *ModelToContractChartOfAccountResponse(&child)
		}
	}

	return contractResp
}

// Account Mappers
func ContractToModelCreateAccountRequest(req *contract.CreateAccountRequest) *models.CreateAccountRequest {
	return &models.CreateAccountRequest{
		ChartOfAccountID: req.ChartOfAccountID,
		Name:             req.Name,
		Number:           req.Number,
		AccountType:      req.AccountType,
		OpeningBalance:   req.OpeningBalance,
		Description:      req.Description,
	}
}

func ContractToModelUpdateAccountRequest(req *contract.UpdateAccountRequest) *models.UpdateAccountRequest {
	return &models.UpdateAccountRequest{
		ChartOfAccountID: req.ChartOfAccountID,
		Name:             req.Name,
		Number:           req.Number,
		AccountType:      req.AccountType,
		OpeningBalance:   req.OpeningBalance,
		Description:      req.Description,
		IsActive:         req.IsActive,
	}
}

func ContractToModelListAccountsRequest(req *contract.ListAccountsRequest) *models.ListAccountsRequest {
	return &models.ListAccountsRequest{
		OrganizationID:   req.OrganizationID,
		OutletID:         req.OutletID,
		ChartOfAccountID: req.ChartOfAccountID,
		AccountType:      req.AccountType,
		IsActive:         req.IsActive,
		IsSystem:         req.IsSystem,
		Page:             req.Page,
		Limit:            req.Limit,
	}
}

func ModelToContractAccountResponse(resp *models.AccountResponse) *contract.AccountResponse {
	contractResp := &contract.AccountResponse{
		ID:               resp.ID,
		OrganizationID:   resp.OrganizationID,
		OutletID:         resp.OutletID,
		ChartOfAccountID: resp.ChartOfAccountID,
		Name:             resp.Name,
		Number:           resp.Number,
		AccountType:      resp.AccountType,
		OpeningBalance:   resp.OpeningBalance,
		CurrentBalance:   resp.CurrentBalance,
		Description:      resp.Description,
		IsActive:         resp.IsActive,
		IsSystem:         resp.IsSystem,
		CreatedAt:        resp.CreatedAt.Format(time.RFC3339),
		UpdatedAt:        resp.UpdatedAt.Format(time.RFC3339),
	}

	if resp.ChartOfAccount != nil {
		contractResp.ChartOfAccount = ModelToContractChartOfAccountResponse(resp.ChartOfAccount)
	}

	return contractResp
}
