import { NextResponse } from 'next/server'
import { prisma } from '@/libs/prisma'
import { convertToSnakeCase } from '@/utils/common-utils'
import { equal } from 'assert'
/**
 * 검색 파라미터
 */
type SearchParams = {
  keyword?: string | null // 검색어
  searchOption?: string | null // 검색 옵션 (select 옵션)
  isMySurvey?: string | null // 내가 작성한 매물
  sort?: string | null // 정렬 방식
  offset?: string | null
  role?: string | null // 회원권한한
  store?: string | null // 판매점ID
  builderNo?: string | null // 시공ID
}

type WhereCondition = {
  AND: any[]
  OR?: any[]
  [key: string]: any
}

// 검색 가능한 필드 옵션
const SEARCH_OPTIONS = [
  'BUILDING_NAME', // 건물명
  'REPRESENTATIVE', // 담당자
  'STORE', // 판매점
  'CONSTRUCTION_POINT', // 시공점
  'CUSTOMER_NAME', // 고객명
  'POST_CODE', // 우편번호
  'ADDRESS', // 주소
  'ADDRESS_DETAIL', // 상세주소
] as const

// 페이지당 항목 수
const ITEMS_PER_PAGE = 10

/**
 * 키워드 검색 조건 생성 함수
 * @param keyword 검색 키워드
 * @param searchOption 검색 옵션
 * @returns 검색 조건 객체
 */
const createKeywordSearchCondition = (keyword: string, searchOption: string): WhereCondition => {
  const where: WhereCondition = { AND: [] }

  if (searchOption === 'all') {
    // 모든 필드 검색 시 OR 조건 사용
    where.OR = []

    // ID가 숫자인 경우 ID 검색 조건 추가
    if (keyword.match(/^\d+$/) || !isNaN(Number(keyword))) {
      where.OR.push({
        ID: { equals: Number(keyword) },
      })
    }

    where.OR.push(
      ...SEARCH_OPTIONS.map((field) => ({
        [field]: { contains: keyword },
      })),
    )
  } else if (SEARCH_OPTIONS.includes(searchOption.toUpperCase() as any)) {
    // 특정 필드 검색
    where[searchOption.toUpperCase()] = { contains: keyword }
  } else if (searchOption === 'id') {
    // ID 검색 (숫자 변환 필요)
    const number = Number(keyword)
    if (!isNaN(number)) {
      where.ID = { equals: number }
    } else {
      // 유효하지 않은 ID 검색 시 빈 결과 반환
      where.ID = { equals: null }
    }
  }
  return where
}

/**
 * 회원 역할별 검색 조건 생성 함수
 * @param params 검색 파라미터
 * @returns 검색 조건 객체
 */
const createMemberRoleCondition = (params: SearchParams): WhereCondition => {
  const where: WhereCondition = { AND: [] }

  switch (params.role) {
    case 'Admin': // 1차점
      where.OR = [
        {
          // 같은 판매점에서 작성한 제출/제출되지 않은 매물
          AND: [{ STORE: { equals: params.store } }],
        },
        {
          // MUSUBI (시공권한 X) 가 ORDER 에 제출한 매물
          AND: [{ SUBMISSION_TARGET_ID: { equals: params.store } }, { SUBMISSION_STATUS: { equals: true } }],
        },
      ]
      break

    case 'Admin_Sub': // 2차점
      where.OR = [
        {
          // MUSUBI (시공권한 X) 같은 판매점에서 작성한 제출/제출되지 않은 매물
          AND: [
            { STORE: { equals: params.store } },
            {
              OR: [{ CONSTRUCTION_POINT: { equals: null } }, { CONSTRUCTION_POINT: { equals: '' } }],
            },
          ],
        },
        {
          // MUSUBI (시공권한 O) 가 MUSUBI 에 제출한 매물 + PARTNER 가 제출한 매물
          AND: [
            { SUBMISSION_TARGET_ID: { equals: params.store } },
            { CONSTRUCTION_POINT: { not: null } },
            { CONSTRUCTION_POINT: { not: '' } },
            { SUBMISSION_STATUS: { equals: true } },
          ],
        },
      ]
      break

    case 'Builder': // MUSUBI (시공권한 O)
    case 'Partner': // PARTNER
      // 같은 시공ID에서 작성된 매물
      where.AND?.push({
        CONSTRUCTION_POINT: { equals: params.builderNo },
      })
      break

    case 'T01':
      where.OR = [
        {
          NOT: {
            SRL_NO: {
              startsWith: '一時保存',
            },
          },
        },
        {
          STORE: {
            equals: params.store,
          },
        },
      ]
      break
    case 'User':
      // 모든 매물 조회 가능 (추가 조건 없음)
      break
  }

  return where
}

/**
 * GET 핸들러 - 설문 목록 조회
 */
export async function GET(request: Request) {
  try {
    // URL 파라미터 파싱
    const { searchParams } = new URL(request.url)
    const params: SearchParams = {
      keyword: searchParams.get('keyword'),
      searchOption: searchParams.get('searchOption'),
      isMySurvey: searchParams.get('isMySurvey'),
      sort: searchParams.get('sort'),
      offset: searchParams.get('offset'),
      role: searchParams.get('role'),
      store: searchParams.get('store'),
      builderNo: searchParams.get('builderNo'),
    }

    // 검색 조건 구성
    const where: WhereCondition = { AND: [] }

    // 내가 작성한 매물 조건 적용
    if (params.isMySurvey) {
      where.AND.push({ REPRESENTATIVE: params.isMySurvey })
    }

    // 키워드 검색 조건 적용
    if (params.keyword && params.searchOption) {
      where.AND.push(createKeywordSearchCondition(params.keyword, params.searchOption))
    }

    // 회원 유형 조건 적용
    const roleCondition = createMemberRoleCondition(params)
    if (Object.keys(roleCondition).length > 0) {
      where.AND.push(roleCondition)
    }

    // 페이지네이션 데이터 조회
    //@ts-ignore
    const surveys = await prisma.SD_SURVEY_SALES_BASIC_INFO.findMany({
      where,
      orderBy: params.sort === 'created' ? { REG_DT: 'desc' } : { UPT_DT: 'desc' },
      skip: Number(params.offset),
      take: ITEMS_PER_PAGE,
    })
    // 전체 개수만 조회
    //@ts-ignore
    const count = await prisma.SD_SURVEY_SALES_BASIC_INFO.count({ where })
    return NextResponse.json({ data: { data: surveys, count: count } })
  } catch (error) {
    console.error(error)
    return NextResponse.json({ error: 'Fail Read Survey' }, { status: 500 })
  }
}

/**
 * PUT 핸들러 - 상세 정보 추가
 */
export async function PUT(request: Request) {
  try {
    const body = await request.json()

    // 상세 정보 생성을 위한 데이터 구성
    const detailInfo = {
      ...body.detail_info,
      BASIC_INFO_ID: body.id,
    }

    // 상세 정보 생성
    //@ts-ignore
    await prisma.SD_SURVEY_SALES_DETAIL_INFO.create({
      data: detailInfo,
    })

    return NextResponse.json({
      message: 'Success Update Survey',
    })
  } catch (error) {
    console.error(error)
    return NextResponse.json({ error: 'Fail Update Survey' }, { status: 500 })
  }
}

export async function POST(request: Request) {
  try {
    const body = await request.json()

    // 임시 저장 시 임시저장 + 000 으로 저장
    // 기본 저장 시 판매점ID + yyMMdd + 000 으로 저장
    const baseSrlNo =
      body.survey.srlNo ??
      body.storeId +
        new Date().getFullYear().toString().slice(-2) +
        (new Date().getMonth() + 1).toString().padStart(2, '0') +
        new Date().getDate().toString().padStart(2, '0')

    // @ts-ignore
    const lastSurvey = await prisma.SD_SURVEY_SALES_BASIC_INFO.findFirst({
      where: {
        SRL_NO: {
          startsWith: body.storeId,
        },
      },
      orderBy: {
        SRL_NO: 'desc',
      },
    })

    // 마지막 번호 추출
    const lastNumber = lastSurvey ? parseInt(lastSurvey.SRL_NO.slice(-3)) : 0

    // 새로운 srlNo 생성 - 임시저장일 경우 '임시저장' 으로 저장
    const newSrlNo = baseSrlNo.startsWith('一時保存') ? baseSrlNo : baseSrlNo + (lastNumber + 1).toString().padStart(3, '0')

    const { detailInfo, ...basicInfo } = body.survey
    // @ts-ignore
    const result = await prisma.SD_SURVEY_SALES_BASIC_INFO.create({
      data: {
        ...convertToSnakeCase(basicInfo),
        SRL_NO: newSrlNo,
        DETAIL_INFO: {
          create: convertToSnakeCase(detailInfo),
        },
      },
    })
    return NextResponse.json(result)
  } catch (error) {
    console.error(error)
    return NextResponse.json({ error: 'Fail Create Survey' }, { status: 500 })
  }
}
