/home/bdqbpbxa/dev-subdomains/admin.pixory.goodface.com.ua/src/api/project/controllers/project.ts
import { factories } from '@strapi/strapi'
import { ValidationError } from 'yup';
import { Context } from 'koa'
import { createProjectBodySchema } from '../common/schemas/create-project-schema';
import { CreateProjectBody } from '../common/schemas/create-project-body';
import { ProjectService } from '../services/project';
import { UserService } from 'src/api/my-user/services/user';

const populateFields = {
  bookSize: true,
  bookType: true,
  paperFinish: true,
  product: true,
}

export default factories.createCoreController('api::project.project', ({ strapi }) => ({
  async find(ctx: Context) {
    const userId = ctx.state.user?.id;
    if (!userId) {
      return ctx.unauthorized('You must be logged in to view addresses');
    }

    const projects = await strapi.db.query('api::project.project').findMany({
      where: { user: userId },
      populate: populateFields,
    });
    return this.transformResponse(projects);
  },  
    
    async create(ctx: Context) {
      try {
        if (!ctx.state.user) {
          return ctx.unauthorized('You must be authenticated to create an address');
        }
  
        const userService = new UserService(strapi);
        const user = await userService.get(ctx.state.user.id);
  
        createProjectBodySchema.validateSync(ctx.request?.body || {});
        const body = ctx.request.body as CreateProjectBody;

        const product = await strapi.db.query('api::product.product').findOne({
          where: { id: body.productId },
        });
        if (!product) {
          return ctx.badRequest('Product not found');
        }
  
        const newProject = await strapi.db.query('api::project.project').create({
          data: {
            ...body,
            user: user.id,
            product: { set: product.id }
          },
          populate: {
            product: true
          }
        });

        return ctx.send(newProject);
      } catch (error) {
        if (error instanceof ValidationError) {
          return ctx.badRequest('Validation error', error.errors);
        }
  
        strapi.log.error('Error creating address:', error);
        return ctx.internalServerError('An error occurred while creating the address');
      }
    },
  
    async delete(ctx: Context) {
      try {
        const user = ctx.state.user;
        const id = ctx.params.id;
  
        if (!user) {
          return ctx.unauthorized('You must be authenticated to delete an project');
        }
  
        const project = await strapi.db.query('api::project.project').findOne({
          where: { id },
        });
  
        if (!project) {
          return ctx.notFound('Project not found');
        }
  
        await strapi.db.query('api::project.project').delete({ where: { id } });
        return ctx.send({ id: project.id });
      } catch (error) {
        strapi.log.error('Error deleting address:', error);
        return ctx.internalServerError('An error occurred while deleting the address');
      }
    },

  async setBookSize(ctx: Context) {
    const { id } = ctx.params;
    const { bookSizeId } = ctx.request.body;

    if (!id || !bookSizeId) {
      return ctx.badRequest('Project ID and Book Size ID are required');
    }

    const project = await strapi.db.query('api::project.project').findOne({
      where: { id },
    });

    if (!project) {
      return ctx.notFound('Project not found');
    }

    const bookSize = await strapi.db.query('api::book-size.book-size').findOne({
      where: { id: bookSizeId },
    });

    if (!bookSize) {
      return ctx.notFound('Book Size not found');
    }

    const service = new ProjectService(strapi);
    const updatedProject = await service.update(id, { bookSize: bookSize.id });

    return ctx.send(updatedProject);
  },

  async setBookType(ctx: Context) {
    const { id } = ctx.params;
    const { bookTypeId } = ctx.request.body;

    if (!id || !bookTypeId) {
      return ctx.badRequest('Project ID and Book Size ID are required');
    }

    const project = await strapi.db.query('api::project.project').findOne({
      where: { id },
    });

    if (!project) {
      return ctx.notFound('Project not found');
    }

    const bookType = await strapi.db.query('api::book-size.book-size').findOne({
      where: { id: bookTypeId },
    });

    if (!bookType) {
      return ctx.notFound('Book Type not found');
    }
    
    const service = new ProjectService(strapi);
    const updatedProject = await service.update(id, { bookType: bookType.id });

    return ctx.send(updatedProject);
  },

  async setPaperFinish(ctx: Context) {
    const { id } = ctx.params;
    const { paperFinishId } = ctx.request.body;

    if (!id || !paperFinishId) {
      return ctx.badRequest('Project ID and Paper Finish ID are required');
    }

    const project = await strapi.db.query('api::project.project').findOne({
      where: { id },
    });

    if (!project) {
      return ctx.notFound('Project not found');
    }

    const paperFinish = await strapi.db.query('api::paper-finish.paper-finish').findOne({
      where: { id: paperFinishId },
    });

    if (!paperFinish) {
      return ctx.notFound('Paper Finish not found');
    }

    const service = new ProjectService(strapi);
    const updatedProject = await service.update(id, { paperFinish: paperFinish.id });

    return ctx.send(updatedProject);
  },
}));