import { Response, NextFunction, Application } from "express";
import { Request } from "express-jwt";
import { ReturnHelper } from "../helpers/express/return";
import { OrmHelper } from "../helpers/orm";
import Joi from "joi";
import { ILogObj, Logger } from "tslog";
import { Language } from "../langs/lang";
import { Paging } from "entity";
import CommonHelper from "../helpers/common";
import * as fastcsv from 'fast-csv';
import dayjs from "dayjs";
import { Province, City, Subdistrict, Ward } from "entity";

const log: Logger<ILogObj> = new Logger({ name: '[RegionController]', type: 'pretty' });

export class RegionController {
    static async province(req: Request, res: Response, next: NextFunction): Promise<Response> {
        /*
        #swagger.tags = ['Region']
        #swagger.security = [{
            "bearerAuth": []
        }]
        */

        try {
            const repo = OrmHelper.DB.getRepository(Province);

            const res_count = repo.createQueryBuilder("province");
            const res_list = repo.createQueryBuilder("province");

            const current_page = 1;
            const total_count_data = await res_count.getCount();
            const list_data = await res_list.getMany();
            const count_data = CommonHelper.countObject(list_data);

            return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, count_data, current_page, total_count_data, list_data);
        } catch (e: unknown) {
            log.error(e);
            const err = e as Error;

            return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_view, err.message);
        }
    }

    static async city(req: Request, res: Response, next: NextFunction): Promise<Response> {
        /*
        #swagger.tags = ['Region']
        #swagger.security = [{
            "bearerAuth": []
        }]
        #swagger.parameters['province_code'] = {
            in: 'path',
            description: 'Province Code.',
            required: true,
            type: 'string'
        }
        */

        try {
            const { province_code } = req.params;

            if (!/^\d{2}$/.test(province_code)) {
                return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, 0, 1, 0, []);
            }

            const repo = OrmHelper.DB.getRepository(City);
            const res_count = repo.createQueryBuilder("city")
                .where("city.code LIKE :province_code", { province_code: `${province_code}%` });
            const res_list = repo.createQueryBuilder("city")
                .where("city.code LIKE :province_code", { province_code: `${province_code}%` });

            const current_page = 1;
            const total_count_data = await res_count.getCount();
            const list_data = await res_list.getMany();
            const count_data = CommonHelper.countObject(list_data);

            return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, count_data, current_page, total_count_data, list_data);
        } catch (e: unknown) {
            log.error(e);
            const err = e as Error;
            return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_view, err.message);
        }
    }

    static async subdistrict(req: Request, res: Response, next: NextFunction): Promise<Response> {
        /*
        #swagger.tags = ['Region']
        #swagger.security = [{
            "bearerAuth": []
        }]
        #swagger.parameters['city_code'] = {
            in: 'path',
            description: 'City Code.',
            required: true,
            type: 'string'
        }
        */

        try {
            const { city_code } = req.params;

            if (!/^\d{2}\.\d{2}$/.test(city_code)) {
                return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, 0, 1, 0, []);
            }

            const repo = OrmHelper.DB.getRepository(Subdistrict);
            const res_count = repo.createQueryBuilder("subdistrict")
                .where("subdistrict.code LIKE :city_code", { city_code: `${city_code}%` });
            const res_list = repo.createQueryBuilder("subdistrict")
                .where("subdistrict.code LIKE :city_code", { city_code: `${city_code}%` });

            const current_page = 1;
            const total_count_data = await res_count.getCount();
            const list_data = await res_list.getMany();
            const count_data = CommonHelper.countObject(list_data);

            return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, count_data, current_page, total_count_data, list_data);
        } catch (e: unknown) {
            log.error(e);
            const err = e as Error;
            return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_view, err.message);
        }
    }

    static async ward(req: Request, res: Response, next: NextFunction): Promise<Response> {
        /*
        #swagger.tags = ['Region']
        #swagger.security = [{
            "bearerAuth": []
        }]
        #swagger.parameters['subdistric_code'] = {
            in: 'path',
            description: 'Subdistric Code.',
            required: true,
            type: 'string'
        }
        */

        try {
            const { subdistric_code } = req.params;

            if (!/^\d{2}\.\d{2}\.\d{2}$/.test(subdistric_code)) {
                return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, 0, 1, 0, []);
            }

            const repo = OrmHelper.DB.getRepository(Ward);
            const res_count = repo.createQueryBuilder("ward")
                .where("ward.code LIKE :subdistric_code", { subdistric_code: `${subdistric_code}%` });
            const res_list = repo.createQueryBuilder("ward")
                .where("ward.code LIKE :subdistric_code", { subdistric_code: `${subdistric_code}%` });

            const current_page = 1;
            const total_count_data = await res_count.getCount();
            const list_data = await res_list.getMany();
            const count_data = CommonHelper.countObject(list_data);

            return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, count_data, current_page, total_count_data, list_data);
        } catch (e: unknown) {
            log.error(e);
            const err = e as Error;
            return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_view, err.message);
        }
    }
}