import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Query,
  Req,
  UploadedFiles,
  UseGuards,
  UseInterceptors
} from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';
import { ApiBearerAuth, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/user/jwt.guard';
import { FaxHistoryQueryDto, ResendFaxDto, SendFaxBatchDto, SendFaxDto } from './fax.dto';
import { FaxService } from './fax.service';

@ApiTags('사용자 - FAX')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('user/fax')
export class FaxUserController {
  constructor(private readonly faxService: FaxService) {}

  @Post('send')
  @ApiOperation({ summary: 'FAX 발송 (여러 파일 지원)' })
  @ApiConsumes('multipart/form-data')
  @UseInterceptors(
    FilesInterceptor('files', 100, { // TODO: 테스트 후 20으로 원복
      limits: {
        fileSize: 100 * 1024 * 1024, // TODO: 테스트 후 10MB로 원복
      },
    })
  )
  async sendFax(
    @Req() req,
    @Body() dto: SendFaxDto,
    @UploadedFiles() files: Express.Multer.File[]
  ) {
    // 한글 파일명 디코딩
    if (files) {
      files.forEach(file => {
        try {
          // 여러 인코딩 시도
          const decoded = Buffer.from(file.originalname, 'latin1').toString('utf8');
          // UTF-8로 정상 디코딩되었는지 확인
          if (decoded && !decoded.includes('�')) {
            file.originalname = decoded;
          } else {
            // binary로 재시도
            file.originalname = Buffer.from(file.originalname, 'binary').toString('utf8');
          }
        } catch (error) {
          // 파일명 디코딩 실패
        }
      });
    }

    // 디버깅 로그
    console.log('[FAX SEND] req.user:', req.user);
    console.log('[FAX SEND] req.cookies._aT:', req.cookies?._aT ? '존재함' : '없음');

    if (!req.user || !req.user.memId) {
      throw new Error('로그인 정보를 찾을 수 없습니다. 다시 로그인해주세요.');
    }

    const memId = req.user.memId;

    // ivhId가 없고 파일도 없으면 에러
    if (!dto.ivhId && (!files || files.length === 0)) {
      throw new Error('파일이 없습니다.');
    }

    try {
      const result = await this.faxService.sendFaxWithMultipleFiles({
        memId,
        ivhId: dto.ivhId,
        receiverName: dto.receiverName,
        receiverFax: dto.receiverFax,
        files: files || [],
        pageCount: dto.pageCount,
        originalFaxHistoryId: dto.originalFaxHistoryId,
        batchId: dto.batchId,
      });

      return result;
    } catch (error) {
      throw error;
    }
  }

  @Get('history')
  @ApiOperation({ summary: '내 FAX 발송 내역 조회' })
  async getMyFaxHistory(@Req() req, @Query() query: FaxHistoryQueryDto) {
    const memId = req.user.memId;

    return this.faxService.getFaxHistoryList({
      page: query.page || 1,
      limit: query.limit || 20,
      status: query.status,
      memId,
    });
  }

  @Post('resend')
  @ApiOperation({ summary: 'FAX 재발송 (본인 FAX만 가능, 머니 차감)' })
  async resendFax(@Req() req, @Body() dto: ResendFaxDto) {
    const memId = req.user.memId;
    return this.faxService.resendFaxForUser(dto.fxhId, memId);
  }

  @Post('send-batch')
  @ApiOperation({ summary: 'FAX 배치 발송 (여러 보험사 청구서를 한 번에 발송, 머니 1회 차감)' })
  @ApiConsumes('multipart/form-data')
  @UseInterceptors(
    FilesInterceptor('files', 200, { // TODO: 테스트 후 60으로 원복
      limits: {
        fileSize: 100 * 1024 * 1024, // TODO: 테스트 후 10MB로 원복
      },
    })
  )
  async sendFaxBatch(
    @Req() req,
    @Body() dto: SendFaxBatchDto,
    @UploadedFiles() files: Express.Multer.File[]
  ) {
    // 한글 파일명 디코딩
    if (files) {
      files.forEach(file => {
        try {
          const decoded = Buffer.from(file.originalname, 'latin1').toString('utf8');
          if (decoded && !decoded.includes('�')) {
            file.originalname = decoded;
          } else {
            file.originalname = Buffer.from(file.originalname, 'binary').toString('utf8');
          }
        } catch (error) {
          // 파일명 디코딩 실패
        }
      });
    }

    if (!req.user || !req.user.memId) {
      throw new Error('로그인 정보를 찾을 수 없습니다. 다시 로그인해주세요.');
    }

    const memId = req.user.memId;

    // items JSON 파싱
    let items: Array<{
      receiverName: string;
      receiverFax?: string;
      pageCount: number;
      fileIndex?: number;
    }>;

    try {
      items = JSON.parse(dto.items);
    } catch (error) {
      throw new Error('발송 항목 데이터가 올바르지 않습니다.');
    }

    if (!items || items.length === 0) {
      throw new Error('발송할 청구서가 없습니다.');
    }

    // 파일 분배: 청구서 파일과 첨부파일 구분
    // 파일 순서: 청구서1, 청구서2, ..., 첨부파일1, 첨부파일2
    const invoiceCount = items.length;
    const invoiceFiles = files.slice(0, invoiceCount);
    const attachedFiles = files.slice(invoiceCount);

    // 각 item에 파일 매핑
    const itemsWithFiles = items.map((item, index) => ({
      receiverName: item.receiverName,
      receiverFax: item.receiverFax,
      pageCount: item.pageCount,
      files: invoiceFiles[index] ? [invoiceFiles[index]] : [],
    }));

    try {
      const result = await this.faxService.sendFaxBatch({
        memId,
        ivhId: dto.ivhId,
        items: itemsWithFiles,
        batchId: dto.batchId,
        attachedFiles,
      });

      return result;
    } catch (error) {
      throw error;
    }
  }

  @Get('config')
  @ApiOperation({ summary: 'FAX 설정 조회 (장당 차감머니 등)' })
  async getFaxConfig() {
    return this.faxService.getFaxConfig();
  }

  @Get('status/:jobId')
  @ApiOperation({ summary: '✅ FAX 발송 상태 조회 (vFax jobId 기준)' })
  async getFaxStatus(@Param('jobId') jobId: string) {
    return this.faxService.getFaxStatus(jobId);
  }

  @Get('history/:fxhId/status')
  @ApiOperation({ summary: '✅ FAX 발송 내역의 최신 상태 조회 (fxhId 기준)' })
  async getFaxHistoryStatus(@Param('fxhId') fxhId: number) {
    // 팩스 히스토리에서 jobId 조회
    const history = await this.faxService.getFaxHistoryDetail(fxhId);
    if (!history.fxhFaxCode) {
      throw new Error('팩스 발송 코드(jobId)가 없습니다.');
    }

    // vFax API로 상태 조회
    return this.faxService.getFaxStatus(history.fxhFaxCode);
  }
}
