# -*- coding: utf-8 -*-
"""
법정 기준 데이터 모듈 (사용자 매뉴얼 기능 이식용)
- 개발가능지 분석 기준 초기값 (입지분석)
- 토지형상 판정 기준 (과소필지/세장형/부정형)
- 정비사업·소규모정비사업 구역지정 요건 (법률분석)
- 허용용도 간이 매트릭스 (용도지역 × 건축물 용도)
- 건설공사비지수·용지구성 프리셋 (사업비분석)

주의: 모든 수치는 법령·고시·조례에 따라 변동될 수 있는 '참고용 추정 기준'이다.
      실제 인허가·구역지정 판단은 관할 행정청과 자치법규 확인이 필요하며,
      UI에서 사용자가 직접 수정할 수 있도록 초기값으로만 사용한다.

이 모듈은 qgis/PyQt를 import하지 않는다 (QGIS 밖에서 단독 검증 가능).
"""

# ---------------------------------------------------------------------------
# 1. 개발가능지 분석 기준 초기값 (입지분석 > 개발가능지 분석)
#    - 표고: 기준 해발고도 대비 개발가능 표고차 (개발행위허가 운영지침 참고)
#    - 경사: 급경사 기준 (지자체 도시계획조례 통상 15~20도 범위)
#    - 환경등급: 생태자연도/식생영급/국토환경성평가 제외 기준
# ---------------------------------------------------------------------------
DEV_FEASIBILITY_DEFAULTS = {
    'base_elevation': None,       # 기준 해발고도(m). None이면 대상지 최저 표고 사용
    'dev_elevation_limit': 50.0,  # 기준 표고 대비 개발가능 표고차(m)
    'steep_slope_deg': 20.0,      # 급경사 기준(도) - 이상이면 개발 곤란
    'eco_grade_exclude': 1,       # 생태자연도 1등급(이하 값) 제외
    'veg_age_exclude': 5,         # 식생 5영급 이상 제외 (50년생 이상)
    'env_assess_exclude': 1,      # 국토환경성평가 1등급(이하 값) 제외
}

# ---------------------------------------------------------------------------
# 2. 토지형상 판정 기준 (입지분석 > 토지형상)
#    - 과소필지: 건축법 시행령 제80조(대지 분할 제한) + 서울시 도시정비조례(90m2) 참고
#    - 세장형: 최소외접직사각형(OMBB) 장변/단변 비
#    - 부정형: 필지면적/OMBB면적 비(직사각형 충실도) 미만
# ---------------------------------------------------------------------------
MIN_PARCEL_AREA_BY_ZONE = {
    '주거지역': 90.0,
    '상업지역': 150.0,
    '공업지역': 150.0,
    '녹지지역': 200.0,
    '기타': 60.0,
}

SHAPE_CRITERIA = {
    'slender_ratio': 4.0,            # 세장형: 장변/단변 비가 이 값 초과
    'irregular_rectangularity': 0.5,  # 부정형: 면적/OMBB면적 비가 이 값 미만
}

# 결과수정 클릭 토글 순환 순서 (1클릭 과소 → 2클릭 부정형·세장형 → 3클릭 일반)
SHAPE_STATES = ['일반', '과소', '부정형·세장형']

# ---------------------------------------------------------------------------
# 3. 정비사업 구역지정 요건 (법률분석 > 도시개발분석 > 정비사업)
#    근거: 도시 및 주거환경정비법 시행령 별표1 + 서울시 도시 및 주거환경정비 조례 참고 간이판
#    요건 dict:
#      name      요건명
#      unit      단위
#      threshold 기준값
#      op        비교 연산 ('>=': 현황>=기준 충족 / '<=': 현황<=기준 충족)
#      mandatory True=필수요건, False=선택요건(1개 이상 충족)
#      auto_key  현황 자동산출 키(없으면 None → 수동 입력)
# ---------------------------------------------------------------------------
REDEV_REQUIREMENTS = {
    '재개발사업': {
        '서울': [
            {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
             'mandatory': True, 'auto_key': 'deterioration_ratio'},
            {'name': '구역면적', 'unit': 'm2', 'threshold': 10000.0, 'op': '>=',
             'mandatory': True, 'auto_key': 'district_area'},
            {'name': '과소필지 비율', 'unit': '%', 'threshold': 40.0, 'op': '>=',
             'mandatory': False, 'auto_key': 'small_parcel_ratio'},
            {'name': '호수밀도', 'unit': '호/ha', 'threshold': 60.0, 'op': '>=',
             'mandatory': False, 'auto_key': None},
            {'name': '접도율(4m 이상 도로)', 'unit': '%', 'threshold': 40.0, 'op': '<=',
             'mandatory': False, 'auto_key': None},
        ],
        '지방': [
            {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
             'mandatory': True, 'auto_key': 'deterioration_ratio'},
            {'name': '구역면적', 'unit': 'm2', 'threshold': 10000.0, 'op': '>=',
             'mandatory': True, 'auto_key': 'district_area'},
            {'name': '과소필지 비율', 'unit': '%', 'threshold': 50.0, 'op': '>=',
             'mandatory': False, 'auto_key': 'small_parcel_ratio'},
            {'name': '호수밀도', 'unit': '호/ha', 'threshold': 70.0, 'op': '>=',
             'mandatory': False, 'auto_key': None},
            {'name': '접도율(4m 이상 도로)', 'unit': '%', 'threshold': 30.0, 'op': '<=',
             'mandatory': False, 'auto_key': None},
        ],
    },
    '재건축사업': {
        '서울': [
            {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
             'mandatory': True, 'auto_key': 'deterioration_ratio'},
            {'name': '구역면적', 'unit': 'm2', 'threshold': 10000.0, 'op': '>=',
             'mandatory': True, 'auto_key': 'district_area'},
            {'name': '기존 세대수', 'unit': '세대', 'threshold': 200.0, 'op': '>=',
             'mandatory': False, 'auto_key': None},
        ],
        '지방': [
            {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
             'mandatory': True, 'auto_key': 'deterioration_ratio'},
            {'name': '구역면적', 'unit': 'm2', 'threshold': 10000.0, 'op': '>=',
             'mandatory': True, 'auto_key': 'district_area'},
            {'name': '기존 세대수', 'unit': '세대', 'threshold': 200.0, 'op': '>=',
             'mandatory': False, 'auto_key': None},
        ],
    },
    '주거환경개선사업': {
        '서울': [
            {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
             'mandatory': True, 'auto_key': 'deterioration_ratio'},
            {'name': '호수밀도', 'unit': '호/ha', 'threshold': 80.0, 'op': '>=',
             'mandatory': False, 'auto_key': None},
            {'name': '과소필지 비율', 'unit': '%', 'threshold': 50.0, 'op': '>=',
             'mandatory': False, 'auto_key': 'small_parcel_ratio'},
            {'name': '접도율(4m 이상 도로)', 'unit': '%', 'threshold': 20.0, 'op': '<=',
             'mandatory': False, 'auto_key': None},
        ],
        '지방': [
            {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
             'mandatory': True, 'auto_key': 'deterioration_ratio'},
            {'name': '호수밀도', 'unit': '호/ha', 'threshold': 70.0, 'op': '>=',
             'mandatory': False, 'auto_key': None},
            {'name': '과소필지 비율', 'unit': '%', 'threshold': 50.0, 'op': '>=',
             'mandatory': False, 'auto_key': 'small_parcel_ratio'},
        ],
    },
    '도시정비형재개발사업': {
        '서울': [
            {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
             'mandatory': True, 'auto_key': 'deterioration_ratio'},
            {'name': '구역면적', 'unit': 'm2', 'threshold': 10000.0, 'op': '>=',
             'mandatory': True, 'auto_key': 'district_area'},
            {'name': '과소필지 비율', 'unit': '%', 'threshold': 40.0, 'op': '>=',
             'mandatory': False, 'auto_key': 'small_parcel_ratio'},
        ],
        # 지방은 도시정비형 구분이 없어 재개발사업으로 통합 (op cit. 도시정비법 시행령)
    },
}

# 서울 4유형 / 지방 3유형 (매뉴얼: 서울은 도시정비형재개발 포함)
REDEV_SCHEMES_BY_REGION = {
    '서울': ['주거환경개선사업', '재개발사업', '도시정비형재개발사업', '재건축사업'],
    '지방': ['주거환경개선사업', '재개발사업', '재건축사업'],
}

# ---------------------------------------------------------------------------
# 4. 소규모정비사업 요건 (빈집 및 소규모주택 정비에 관한 특례법 시행령 참고 간이판)
# ---------------------------------------------------------------------------
SMALL_REDEV_REQUIREMENTS = {
    '자율주택정비사업': [
        {'name': '기존주택 호수(단독+다세대 합산)', 'unit': '호/세대', 'threshold': 36.0, 'op': '<=',
         'mandatory': True, 'auto_key': None},
        {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
         'mandatory': True, 'auto_key': 'deterioration_ratio'},
    ],
    '가로주택정비사업': [
        {'name': '구역면적', 'unit': 'm2', 'threshold': 10000.0, 'op': '<=',
         'mandatory': True, 'auto_key': 'district_area'},
        {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
         'mandatory': True, 'auto_key': 'deterioration_ratio'},
        {'name': '기존주택 호수(세대수)', 'unit': '호/세대', 'threshold': 20.0, 'op': '>=',
         'mandatory': True, 'auto_key': None},
        {'name': '6m 이상 도로로 둘러싸인 가로구역', 'unit': '여부(1=충족)', 'threshold': 1.0, 'op': '>=',
         'mandatory': True, 'auto_key': None},
    ],
    '소규모재건축사업': [
        {'name': '구역면적(주택단지)', 'unit': 'm2', 'threshold': 10000.0, 'op': '<=',
         'mandatory': True, 'auto_key': 'district_area'},
        {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
         'mandatory': True, 'auto_key': 'deterioration_ratio'},
        {'name': '기존 세대수', 'unit': '세대', 'threshold': 200.0, 'op': '<=',
         'mandatory': True, 'auto_key': None},
    ],
    '소규모재개발사업': [
        {'name': '구역면적(역세권·준공업지역)', 'unit': 'm2', 'threshold': 5000.0, 'op': '<=',
         'mandatory': True, 'auto_key': 'district_area'},
        {'name': '노후·불량건축물 비율', 'unit': '%', 'threshold': 66.7, 'op': '>=',
         'mandatory': True, 'auto_key': 'deterioration_ratio'},
        {'name': '역세권(승강장 350m 이내) 또는 준공업지역', 'unit': '여부(1=충족)', 'threshold': 1.0, 'op': '>=',
         'mandatory': True, 'auto_key': None},
    ],
}

# ---------------------------------------------------------------------------
# 5. 허용용도 간이 매트릭스 (법률분석 > 행위제한분석 > 허용용도분석)
#    근거: 국토계획법 시행령 별표2~별표22 + 건축법 시행령 별표1 (대분류 기준 간이판)
#    - 세부 호수·층수 제한·조례 위임 단서를 모두 반영하지 않은 '대분류 단위' 판정이다.
#    - 값: 'O'=가능(건축 가능) / 'C'=조례위임(지자체 조례로 가능 여부 결정) / 'X'=불가능
#    - 매트릭스에 없는 (용도지역, 용도) 조합은 'X'로 간주한다(희소 dict).
# ---------------------------------------------------------------------------
USE_ZONES = {
    'R1': '제1종전용주거지역',
    'R2': '제2종전용주거지역',
    'R3': '제1종일반주거지역',
    'R4': '제2종일반주거지역',
    'R5': '제3종일반주거지역',
    'RS': '준주거지역',
    'CC': '중심상업지역',
    'CG': '일반상업지역',
    'IG': '일반공업지역',
    'GN': '자연녹지지역',
    'MP': '계획관리지역',
    'AG': '농림지역',
}

# 건축법 시행령 별표1 용도별 건축물 대분류 (1~29호 + 29의2 야영장시설은 30으로 표기)
BUILDING_USES = [
    (1, '단독주택'), (2, '공동주택'), (3, '제1종근린생활시설'), (4, '제2종근린생활시설'),
    (5, '문화 및 집회시설'), (6, '종교시설'), (7, '판매시설'), (8, '운수시설'),
    (9, '의료시설'), (10, '교육연구시설'), (11, '노유자시설'), (12, '수련시설'),
    (13, '운동시설'), (14, '업무시설'), (15, '숙박시설'), (16, '위락시설'),
    (17, '공장'), (18, '창고시설'), (19, '위험물 저장 및 처리시설'), (20, '자동차 관련 시설'),
    (21, '동물 및 식물 관련 시설'), (22, '자원순환 관련 시설'), (23, '교정시설'),
    (24, '국방·군사시설'), (25, '방송통신시설'), (26, '발전시설'), (27, '묘지 관련 시설'),
    (28, '관광 휴게시설'), (29, '장례시설'), (30, '야영장시설'),
]

# 중분류(소분류 간이) - 대분류 선택 시 참고용 하위 항목 (판정은 대분류 기준)
BUILDING_USE_SUBTYPES = {
    1: ['단독주택', '다중주택', '다가구주택', '공관'],
    2: ['아파트', '연립주택', '다세대주택', '기숙사'],
    3: ['소매점(1천m2 미만)', '휴게음식점(300m2 미만)', '이용원·미용원', '의원·치과의원·한의원', '마을회관', '주민운동시설'],
    4: ['일반음식점', '휴게음식점(300m2 이상)', '사무소(500m2 미만)', '학원(500m2 미만)', '노래연습장', '제조업소(500m2 미만)'],
    5: ['공연장', '집회장', '관람장', '전시장', '동·식물원'],
    6: ['교회', '성당', '사찰', '기도원', '납골당(종교시설 부속)'],
    7: ['도매시장', '소매시장', '상점(1천m2 이상)'],
    8: ['여객자동차터미널', '철도시설', '공항시설', '항만시설'],
    9: ['병원(종합병원·치과·한방·요양)', '격리병원'],
    10: ['학교(초·중·고·대학)', '교육원', '직업훈련소', '학원(500m2 이상)', '연구소', '도서관'],
    11: ['아동 관련 시설(어린이집 등)', '노인복지시설', '사회복지시설'],
    12: ['생활권 수련시설', '자연권 수련시설', '유스호스텔'],
    13: ['탁구장·체육도장', '체육관', '운동장'],
    14: ['공공업무시설', '일반업무시설(오피스텔 포함)'],
    15: ['일반숙박시설', '관광숙박시설', '생활숙박시설'],
    16: ['단란주점', '유흥주점', '카지노영업소', '무도장·무도학원'],
    17: ['공장(제조업소 외)'],
    18: ['창고', '하역장', '물류터미널', '집배송시설'],
    19: ['주유소', '액화가스 취급소·판매소', '위험물 제조소·저장소'],
    20: ['주차장', '세차장', '폐차장', '검사장', '매매장', '정비공장', '운전학원·정비학원'],
    21: ['축사', '가축시설', '도축장', '도계장', '작물재배사', '종묘배양시설', '온실'],
    22: ['하수 등 처리시설', '고물상', '폐기물재활용시설', '폐기물처분시설'],
    23: ['교정시설', '갱생보호시설', '소년원·소년분류심사원'],
    24: ['국방·군사시설'],
    25: ['방송국', '전신전화국', '촬영소', '통신용 시설', '데이터센터'],
    26: ['발전소(집단에너지 공급시설 포함)'],
    27: ['화장시설', '봉안당', '묘지 부속 건축물'],
    28: ['야외음악당', '야외극장', '어린이회관', '관망탑', '휴게소'],
    29: ['장례식장', '동물 전용 장례식장'],
    30: ['야영장시설(관리동·취사장 등)'],
}

PERMITTED_USE_MATRIX = {
    # 제1종전용주거지역 (별표2)
    'R1': {1: 'O', 3: 'O', 2: 'C', 4: 'C', 6: 'C', 10: 'C', 11: 'C', 13: 'C', 21: 'C'},
    # 제2종전용주거지역 (별표3)
    'R2': {1: 'O', 2: 'O', 3: 'O', 4: 'C', 5: 'C', 6: 'C', 10: 'C', 11: 'C', 12: 'C', 13: 'C', 21: 'C'},
    # 제1종일반주거지역 (별표4)
    'R3': {1: 'O', 2: 'O', 3: 'O', 10: 'O', 11: 'O', 6: 'O',
           4: 'C', 5: 'C', 9: 'C', 12: 'C', 13: 'C', 18: 'C', 20: 'C', 21: 'C', 23: 'C', 24: 'C', 25: 'C', 26: 'C', 29: 'C'},
    # 제2종일반주거지역 (별표5)
    'R4': {1: 'O', 2: 'O', 3: 'O', 6: 'O', 10: 'O', 11: 'O', 12: 'O',
           4: 'C', 5: 'C', 7: 'C', 9: 'C', 13: 'C', 14: 'C', 17: 'C', 18: 'C', 19: 'C', 20: 'C', 21: 'C',
           22: 'C', 23: 'C', 24: 'C', 25: 'C', 26: 'C', 28: 'C', 29: 'C', 30: 'C'},
    # 제3종일반주거지역 (별표6)
    'R5': {1: 'O', 2: 'O', 3: 'O', 6: 'O', 10: 'O', 11: 'O', 12: 'O',
           4: 'C', 5: 'C', 7: 'C', 8: 'C', 9: 'C', 13: 'C', 14: 'C', 17: 'C', 18: 'C', 19: 'C', 20: 'C',
           21: 'C', 22: 'C', 23: 'C', 24: 'C', 25: 'C', 26: 'C', 28: 'C', 29: 'C', 30: 'C'},
    # 준주거지역 (별표7)
    'RS': {1: 'O', 2: 'O', 3: 'O', 4: 'O', 5: 'O', 6: 'O', 7: 'O', 9: 'O', 10: 'O', 11: 'O', 12: 'O',
           13: 'O', 14: 'O', 25: 'O', 29: 'O',
           8: 'C', 15: 'C', 17: 'C', 18: 'C', 19: 'C', 20: 'C', 21: 'C', 22: 'C', 23: 'C', 24: 'C',
           26: 'C', 27: 'C', 28: 'C', 30: 'C'},
    # 중심상업지역 (별표8)
    'CC': {3: 'O', 4: 'O', 5: 'O', 6: 'O', 7: 'O', 8: 'O', 9: 'O', 10: 'O', 11: 'O', 12: 'O',
           13: 'O', 14: 'O', 15: 'O', 16: 'O', 25: 'O',
           1: 'C', 2: 'C', 17: 'X', 18: 'C', 19: 'C', 20: 'C', 22: 'C', 23: 'C', 24: 'C',
           26: 'C', 28: 'C', 29: 'C', 30: 'C'},
    # 일반상업지역 (별표9)
    'CG': {1: 'C', 2: 'C', 3: 'O', 4: 'O', 5: 'O', 6: 'O', 7: 'O', 8: 'O', 9: 'O', 10: 'O', 11: 'O',
           12: 'O', 13: 'O', 14: 'O', 15: 'O', 16: 'O', 18: 'O', 25: 'O', 29: 'O',
           17: 'X', 19: 'C', 20: 'C', 21: 'C', 22: 'C', 23: 'C', 24: 'C', 26: 'C', 28: 'C', 30: 'C'},
    # 일반공업지역 (별표12)
    'IG': {3: 'O', 4: 'O', 17: 'O', 18: 'O', 19: 'O', 20: 'O', 22: 'O', 26: 'O', 25: 'O',
           1: 'C', 2: 'X', 5: 'C', 6: 'C', 7: 'C', 8: 'C', 9: 'C', 10: 'C', 11: 'C', 12: 'C',
           13: 'C', 14: 'C', 21: 'C', 23: 'C', 24: 'C', 29: 'C', 30: 'C',
           15: 'X', 16: 'X', 27: 'X', 28: 'X'},
    # 자연녹지지역 (별표17)
    'GN': {1: 'O', 3: 'O', 11: 'O', 12: 'O', 21: 'O', 30: 'O',
           2: 'C', 4: 'C', 5: 'C', 6: 'C', 7: 'C', 8: 'C', 9: 'C', 10: 'C', 13: 'C', 18: 'C',
           19: 'C', 20: 'C', 22: 'C', 23: 'C', 24: 'C', 25: 'C', 26: 'C', 27: 'C', 28: 'C', 29: 'C',
           14: 'X', 15: 'X', 16: 'X', 17: 'C'},
    # 계획관리지역 (별표20)
    'MP': {1: 'O', 3: 'O', 18: 'O', 21: 'O', 30: 'O', 19: 'O', 20: 'O',
           2: 'C', 4: 'C', 5: 'C', 6: 'C', 9: 'C', 10: 'C', 11: 'C', 12: 'C', 13: 'C', 15: 'C',
           17: 'C', 22: 'C', 23: 'C', 24: 'C', 25: 'C', 26: 'C', 27: 'C', 28: 'C', 29: 'C',
           7: 'C', 8: 'C', 14: 'X', 16: 'X'},
    # 농림지역 (별표21)
    'AG': {1: 'C', 3: 'C', 6: 'C', 9: 'C', 11: 'C', 18: 'C', 21: 'O', 23: 'C', 24: 'C',
           26: 'C', 27: 'C', 29: 'C', 30: 'C',
           2: 'X', 4: 'X', 5: 'X', 7: 'X', 8: 'X', 10: 'X', 12: 'X', 13: 'X', 14: 'X',
           15: 'X', 16: 'X', 17: 'X', 19: 'X', 20: 'X', 22: 'X', 25: 'X', 28: 'X'},
}

STATUS_LABELS = {'O': '가능', 'C': '조례위임', 'X': '불가능'}

# 조건분석(수동 수정) 선택지 - 매뉴얼의 판단결과 항목
CONDITION_CHOICES = ['자동판정', '가능', '보류', '불가', '조례위임', '지자체협의']

# 용도지역명 → 대분류(과소필지 기준면적용) 매핑 키워드
ZONE_CATEGORY_KEYWORDS = [
    ('주거지역', '주거지역'),
    ('상업지역', '상업지역'),
    ('공업지역', '공업지역'),
    ('녹지지역', '녹지지역'),
]


def match_zone_key(zone_name):
    """용도지역명 문자열 → USE_ZONES 키 정규화 매칭.

    '제2종일반주거지역(7층이하)' 같은 표기 변형을 부분일치로 흡수한다.
    매칭 실패 시 None을 반환한다 (호출측에서 '기타(수동확인)' 처리).
    """
    if not zone_name:
        return None
    name = str(zone_name).strip()
    # 긴 명칭 우선 매칭 (예: '제1종일반주거'가 '제1종전용주거'보다 먼저 걸리지 않도록)
    for key, label in sorted(USE_ZONES.items(), key=lambda kv: -len(kv[1])):
        if label in name:
            return key
    # 축약 표기 보정
    aliases = [
        ('1종전용주거', 'R1'), ('2종전용주거', 'R2'),
        ('1종일반주거', 'R3'), ('2종일반주거', 'R4'), ('3종일반주거', 'R5'),
        ('준주거', 'RS'), ('중심상업', 'CC'), ('일반상업', 'CG'),
        ('근린상업', 'CG'), ('유통상업', 'CG'),
        ('전용공업', 'IG'), ('일반공업', 'IG'), ('준공업', 'IG'),
        ('보전녹지', 'GN'), ('생산녹지', 'GN'), ('자연녹지', 'GN'),
        ('계획관리', 'MP'), ('생산관리', 'MP'), ('보전관리', 'MP'),
        ('농림', 'AG'),
    ]
    for kw, key in aliases:
        if kw in name:
            return key
    return None


def match_zone_category(zone_name):
    """용도지역명 → 과소필지 기준면적 대분류('주거지역' 등) 매칭. 실패 시 '기타'."""
    if not zone_name:
        return '기타'
    name = str(zone_name)
    for kw, category in ZONE_CATEGORY_KEYWORDS:
        if kw in name or kw[:2] in name:  # '주거지역' 또는 '주거' 포함
            return category
    return '기타'


# ---------------------------------------------------------------------------
# 6. 사업비분석 기준 (사업비분석 > 토지이용계획 / 추정사업비)
# ---------------------------------------------------------------------------
# 건설공사비지수 (한국건설기술연구원 공표 참고, 2020=100 기준 간이값)
CONSTRUCTION_COST_INDEX = {
    2020: 100.0,
    2021: 114.3,
    2022: 123.8,
    2023: 127.9,
    2024: 130.2,
    2025: 132.5,
    2026: 134.0,
}
COST_INDEX_BASE_YEAR = 2024  # 아래 단가의 기준년도

# 용지구성 평균비율 프리셋 (%) - 최근 도시개발사업/산업단지 평균 비율 참고 간이값
LANDUSE_RATIO_PRESETS = {
    '도시개발사업(주거형)': [
        ('주택건설용지', 45.0), ('상업·업무용지', 8.0), ('도로', 20.0),
        ('공원·녹지', 18.0), ('학교 등 공공시설', 6.0), ('기타 기반시설', 3.0),
    ],
    '도시개발사업(복합형)': [
        ('주택건설용지', 35.0), ('상업·업무용지', 18.0), ('도로', 20.0),
        ('공원·녹지', 17.0), ('학교 등 공공시설', 5.0), ('기타 기반시설', 5.0),
    ],
    '산업단지': [
        ('산업시설용지', 55.0), ('지원시설용지', 8.0), ('도로', 15.0),
        ('공원·녹지', 12.0), ('공공시설용지', 7.0), ('기타 기반시설', 3.0),
    ],
}

# 추정사업비 단가 (참고용, COST_INDEX_BASE_YEAR 기준)
PROJECT_UNIT_COSTS = {
    'compensation_multiplier': 1.2,   # 보상비 = 공시지가 합계 × 배수 (감정가 보정 간이)
    'site_work_per_m2': 150000.0,     # 부지조성비 (원/m2)
    'infra_per_m2': 80000.0,          # 기반시설설치비 (원/m2)
    'incidental_rate': 0.07,          # 부대비(조사·설계·감리 등) = 직접비 × 비율
    'contingency_rate': 0.05,         # 예비비 = 직접비 × 비율
}


# ---------------------------------------------------------------------------
# 7. 개발용량 분석 기준 (개발성 분석 > 개발용량) — NF-01
#    근거: 국토계획법 시행령 제84조(건폐율 상한)·제85조(용적률 상한) 최대값.
#    실제는 지자체 도시계획조례로 강화(하향)되며, 지구단위계획·고도지구·일조 사선
#    등으로 추가 제한될 수 있는 '법정 상한 참고값'이다. (건폐율%, 용적률%)
# ---------------------------------------------------------------------------
BCR_FAR_BY_ZONE = {
    '제1종전용주거지역': {'bcr': 50.0, 'far': 100.0},
    '제2종전용주거지역': {'bcr': 50.0, 'far': 150.0},
    '제1종일반주거지역': {'bcr': 60.0, 'far': 200.0},
    '제2종일반주거지역': {'bcr': 60.0, 'far': 250.0},
    '제3종일반주거지역': {'bcr': 50.0, 'far': 300.0},
    '준주거지역': {'bcr': 70.0, 'far': 500.0},
    '중심상업지역': {'bcr': 90.0, 'far': 1500.0},
    '일반상업지역': {'bcr': 80.0, 'far': 1300.0},
    '근린상업지역': {'bcr': 70.0, 'far': 900.0},
    '유통상업지역': {'bcr': 80.0, 'far': 1100.0},
    '전용공업지역': {'bcr': 70.0, 'far': 300.0},
    '일반공업지역': {'bcr': 70.0, 'far': 350.0},
    '준공업지역': {'bcr': 70.0, 'far': 400.0},
    '보전녹지지역': {'bcr': 20.0, 'far': 80.0},
    '생산녹지지역': {'bcr': 20.0, 'far': 100.0},
    '자연녹지지역': {'bcr': 20.0, 'far': 100.0},
    '보전관리지역': {'bcr': 20.0, 'far': 80.0},
    '생산관리지역': {'bcr': 20.0, 'far': 80.0},
    '계획관리지역': {'bcr': 40.0, 'far': 100.0},
    '농림지역': {'bcr': 20.0, 'far': 80.0},
    '자연환경보전지역': {'bcr': 20.0, 'far': 80.0},
}

# 개발용량 산출 보조 기준
CAPACITY_DEFAULTS = {
    'floor_height_m': 3.0,    # 평균 층고(m) — 추정 높이 환산용 참고값
    'far_band_step': 100.0,   # 용적률 주제도 구간 폭(%)
}

# 개발용량 매처용 별칭 (BCR_FAR_BY_ZONE 정식 명칭으로 정규화)
_CAPACITY_ALIASES = [
    ('1종전용주거', '제1종전용주거지역'), ('2종전용주거', '제2종전용주거지역'),
    ('1종일반주거', '제1종일반주거지역'), ('2종일반주거', '제2종일반주거지역'),
    ('3종일반주거', '제3종일반주거지역'),
    ('준주거', '준주거지역'),
    ('중심상업', '중심상업지역'), ('일반상업', '일반상업지역'),
    ('근린상업', '근린상업지역'), ('유통상업', '유통상업지역'),
    ('전용공업', '전용공업지역'), ('일반공업', '일반공업지역'),
    ('준공업', '준공업지역'),
    ('보전녹지', '보전녹지지역'), ('생산녹지', '생산녹지지역'),
    ('자연녹지', '자연녹지지역'),
    ('보전관리', '보전관리지역'), ('생산관리', '생산관리지역'),
    ('계획관리', '계획관리지역'),
    ('농림', '농림지역'), ('자연환경보전', '자연환경보전지역'),
]


def match_capacity_zone(zone_name):
    """용도지역명 → BCR_FAR_BY_ZONE 정식 키 매칭. 실패 시 None."""
    if not zone_name:
        return None
    name = str(zone_name).strip()
    # 정식 명칭 직접 포함(긴 명칭 우선)
    for key in sorted(BCR_FAR_BY_ZONE.keys(), key=lambda k: -len(k)):
        if key in name:
            return key
    # 축약 표기 보정(긴 별칭 우선)
    for kw, key in sorted(_CAPACITY_ALIASES, key=lambda kv: -len(kv[0])):
        if kw in name:
            return key
    return None


# ---------------------------------------------------------------------------
# 자가검사 (QGIS 밖에서 python legal_standards.py 로 직접 실행)
# ---------------------------------------------------------------------------
def _self_check():
    errors = []
    use_nos = {no for no, _ in BUILDING_USES}
    for zone, row in PERMITTED_USE_MATRIX.items():
        if zone not in USE_ZONES:
            errors.append(f"매트릭스에 정의되지 않은 용도지역 키: {zone}")
        for use_no, val in row.items():
            if use_no not in use_nos:
                errors.append(f"{zone}: 잘못된 용도 번호 {use_no}")
            if val not in ('O', 'C', 'X'):
                errors.append(f"{zone}/{use_no}: 잘못된 값 {val}")
    for no in use_nos:
        if no not in BUILDING_USE_SUBTYPES:
            errors.append(f"하위분류 누락: 용도 {no}")
    for scheme, regions in REDEV_REQUIREMENTS.items():
        for region, reqs in regions.items():
            for r in reqs:
                missing = {'name', 'unit', 'threshold', 'op', 'mandatory', 'auto_key'} - set(r.keys())
                if missing:
                    errors.append(f"{scheme}/{region}/{r.get('name')}: 누락 필드 {missing}")
                if r['op'] not in ('>=', '<='):
                    errors.append(f"{scheme}/{region}/{r['name']}: 잘못된 op {r['op']}")
    for sub, reqs in SMALL_REDEV_REQUIREMENTS.items():
        for r in reqs:
            if r['op'] not in ('>=', '<='):
                errors.append(f"{sub}/{r['name']}: 잘못된 op {r['op']}")
    total = sum(v for _, v in LANDUSE_RATIO_PRESETS['도시개발사업(주거형)'])
    for preset, rows in LANDUSE_RATIO_PRESETS.items():
        total = sum(v for _, v in rows)
        if abs(total - 100.0) > 0.01:
            errors.append(f"용지비율 프리셋 합계 오류: {preset} = {total}")
    # 개발용량 기준(NF-01) 검증
    for zone, v in BCR_FAR_BY_ZONE.items():
        if not (0 < v['bcr'] <= 100):
            errors.append(f"건폐율 값역 오류: {zone} = {v['bcr']}")
        if v['far'] <= 0:
            errors.append(f"용적률 값역 오류: {zone} = {v['far']}")
    assert match_zone_key('제2종일반주거지역(7층이하)') == 'R4'
    assert match_zone_key('자연녹지지역') == 'GN'
    assert match_zone_key('알수없는지역') is None
    assert match_zone_category('제1종일반주거지역') == '주거지역'
    assert match_capacity_zone('제3종일반주거지역') == '제3종일반주거지역'
    assert match_capacity_zone('준공업지역') == '준공업지역'
    assert match_capacity_zone('알수없는지역') is None
    return errors


if __name__ == '__main__':
    problems = _self_check()
    if problems:
        for p in problems:
            print('FAIL:', p)
        raise SystemExit(1)
    print('legal_standards self-check OK '
          f'(zones={len(USE_ZONES)}, uses={len(BUILDING_USES)}, '
          f'schemes={len(REDEV_REQUIREMENTS)}, small={len(SMALL_REDEV_REQUIREMENTS)}, '
          f'capacity_zones={len(BCR_FAR_BY_ZONE)})')
