import os
import uuid
from http import HTTPStatus
from typing import List

import inject

from app.extensions.utils.enum.aws_enum import S3BucketEnum, S3PathEnum, CloudFrontEnum
from app.extensions.utils.image_helper import S3Helper
from core.domains.cs.dto.cs_dto import (
    CreateCustomerInquiryDto,
    CreateInquiryAttachmentDto,
)
from core.domains.cs.repository.cs_repository import CSRepository
from core.use_case_output import UseCaseSuccessOutput, UseCaseFailureOutput, FailureType


class CSBaseUseCase:
    @inject.autoparams()
    def __init__(self, cs_repo: CSRepository):
        self._cs_repo = cs_repo

    def _check_body_validator(self, body: str) -> dict:
        if not body:
            return dict(status=False, message="empty body")

        if len(body) > 1000:
            return dict(status=False, message="over 1000 char")

        return dict(status=True, message="success")

    def _upload_inquiry_attachments(
        self, dtos: List[CreateInquiryAttachmentDto]
    ) -> None:
        for dto in dtos:
            res = S3Helper.upload(
                bucket=S3BucketEnum.PLANTRA_BUCKET_NAME.value,
                file_name=dto.origin_file,
                object_name=dto.object_name,
                extension=dto.extension,
            )

            if res:
                dto.is_upload = True

    def _get_file_split_object(
        self, dto: CreateCustomerInquiryDto, inquiry_id: int
    ) -> List[CreateInquiryAttachmentDto]:
        results = list()
        for file in dto.files:
            f, extension = os.path.splitext(file.filename)
            uuid_ = str(uuid.uuid4())
            object_name = S3PathEnum.CS_IMGS.value + uuid_ + extension
            path = f"{CloudFrontEnum.PLANTRA_CLOUD_FRONT_DOMAIN.value}/{object_name}"

            create_inquiry_attachment_dto = CreateInquiryAttachmentDto(
                inquiry_id=inquiry_id,
                uuid=uuid_,
                file_name=f,
                path=path,
                extension=extension,
                object_name=object_name,
                origin_file=file,
                is_upload=False,
            )
            results.append(create_inquiry_attachment_dto)

        return results


class CreateCSUseCase(CSBaseUseCase):
    def execute(
        self, dto: CreateCustomerInquiryDto
    ) -> UseCaseSuccessOutput | UseCaseFailureOutput:
        # body validator
        body_validate_result: dict = self._check_body_validator(body=dto.body)
        if not body_validate_result.get("status"):
            return UseCaseFailureOutput(
                type=body_validate_result.get("message"),
                message=FailureType.INVALID_REQUEST_ERROR,
                code=HTTPStatus.BAD_REQUEST,
            )

        if len(dto.files) > 5:
            return UseCaseFailureOutput(
                type="over 5 picture",
                message=FailureType.INVALID_REQUEST_ERROR,
                code=HTTPStatus.BAD_REQUEST,
            )

        inquiry_id: int = self._cs_repo.create_customer_inquiry(dto=dto)

        if dto.files:
            create_inquiry_attachment_dtos: List[
                CreateInquiryAttachmentDto
            ] = self._get_file_split_object(dto=dto, inquiry_id=inquiry_id)
            self._upload_inquiry_attachments(dtos=create_inquiry_attachment_dtos)

            for create_cs_attachment_dto in create_inquiry_attachment_dtos:
                if not create_cs_attachment_dto.is_upload:
                    continue

                self._cs_repo.create_inquiry_attachment(dto=create_cs_attachment_dto)

        return UseCaseSuccessOutput()
