import { Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'
import { FindManyOptions, FindOptionsOrder, In, Repository, UpdateResult } from 'typeorm'
import { InjectRepository } from '@nestjs/typeorm'
import { paginate, Pagination } from 'nestjs-typeorm-paginate'
import { PageRequest } from '../common/dto/page-request'
import { Form } from './entities/form.entity'
import { FormDto } from './dto/form.dto'
import { Field } from './entities/filed.entity'
import { UserField } from './entities/userField.entity'

@Injectable()
export class FormService {
    constructor(
        @InjectRepository(Form)
        private readonly formRepository: Repository<Form>,
        @InjectRepository(Field)
        private readonly filedRepository: Repository<Field>,
        @InjectRepository(UserField)
        private readonly userFieldRepository: Repository<UserField>
    ) {}

    public async create(formDto: FormDto) {
        return await this.formRepository.save(formDto)
    }

    public async createAll(list: Form[]) {}

    public async findById(id: number): Promise<Form> {
        const form = await this.formRepository.findOneBy({
            id: +id
        })

        if (!form) {
            throw new NotFoundException(`Form #${id} not found`)
        }

        return form
    }

    public async findAll(req: PageRequest<Form>) {
        try {
            return await paginate<Form>(this.formRepository, req.page, req.search)
        } catch (error) {}
    }

    async save(form: Partial<Form>) {
        try {
            return await this.formRepository.save(form)
        } catch (error) {
            throw new InternalServerErrorException(error.message)
        }
    }

    async update(form: Partial<Form>) {
        try {
            return await this.formRepository.save(form)
        } catch (error) {
            throw new InternalServerErrorException(error.message)
        }
    }

    async getFileds(formId: string) {
        return await this.filedRepository.findBy({
            formId: formId
        })
    }

    public async findAllFileds(req: PageRequest<Field>) {
        try {
            return await paginate<Field>(this.filedRepository, req.page, req.search)
        } catch (error) {}
    }

    async saveFiled(field: Partial<Field>) {
        console.log('保存filed')
        try {
            return await this.filedRepository.save(field)
        } catch (error) {
            throw new InternalServerErrorException(error.message)
        }
    }

    async updateFiled(field: Partial<Form>) {
        try {
            return await this.filedRepository.save(field)
        } catch (error) {
            throw new InternalServerErrorException(error.message)
        }
    }

    async delete(id: number) {
        await this.formRepository.delete(id)
    }

    async saveUserFileds(fields: Array<Partial<UserField>>) {
        await fields.forEach(async (field) => {
            await this.userFieldRepository.save(field)
        })
    }

    async getUserFields(userId, orgId) {
        const form = await this.formRepository.findOneBy({
            orgId: orgId,
            used: true
        })
        const filedsNum = await this.userFieldRepository.countBy({
            formId: form.id,
            userId: userId
        })
        if (filedsNum) {
            //收集成功
            return {
                code: 1
            }
        } else {
            const fileds = await this.getFileds(String(form.id))
            //未填写返回表单
            return {
                code: 0,
                form: form,
                fileds: fileds
            }
        }
    }

    async getUserFieldsByForm(formId) {
        const fileds = await this.getFileds(formId)
        const filedsNum = await this.userFieldRepository.countBy({
            formId: formId
        })
        let backFileds = <any>[]
        if (filedsNum) {
            const userFileds = await this.userFieldRepository.findBy({
                formId: formId
            })
            let filedMap = new Map()
            userFileds.forEach((userFiled) => {
                if (filedMap.has(userFiled.userId)) {
                    filedMap.set(userFiled.userId, {
                        ...filedMap.get(userFiled.userId),
                        [userFiled.filedId]: userFiled.value
                    })
                } else {
                    filedMap.set(userFiled.userId, {
                        userId: userFiled.userId,
                        [userFiled.filedId]: userFiled.value,
                        createdAt: userFiled.createdAt
                    })
                }
            })
            backFileds = [...filedMap.values()]
            console.log(backFileds)
        }
        return {
            fileds,
            backFileds
        }
    }
}
