import csv
import os
import docx
from docx.shared import Pt, Cm
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import pandas as pd
import re
from docx.shared import Inches, Cm, Pt
from math import ceil
from pathlib import Path

def set_landscape(doc):
    """Устанавливает альбомную ориентацию и узкие поля"""
    section = doc.sections[0]
    new_width, new_height = section.page_height, section.page_width  # Меняем местами ширину и высоту
    section.page_width = new_width
    section.page_height = new_height
    section.top_margin = Cm(1)
    section.bottom_margin = Cm(1)
    section.left_margin = Cm(1)
    section.right_margin = Cm(1)

def set_two_columns(doc):
    """Разделяет текст на две колонки"""
    section = doc.sections[0]
    cols = section._sectPr.find(qn('w:cols'))
    if cols is None:
        cols = OxmlElement('w:cols')
        section._sectPr.append(cols)
    cols.set(qn('w:num'), '2')  # Устанавливаем две колонки

def insert_image(doc, image_path):
    """Вставляет изображение в начало документа"""
    para = doc.add_paragraph()
    run = para.add_run()
    run.add_picture(image_path, width=Cm(6))

def find_rows(csv_file, search_word):
    """Ищет строки в CSV, где 4-й столбец содержит search_word"""
    matched_rows = []
    with open(csv_file, newline='', encoding='utf-8') as file:
        reader = csv.reader(file, delimiter=';')  # Укажите нужный разделитель
        for row in reader:
            if search_word.lower() == row[3].lower():
                matched_rows.append(row)
    return matched_rows

def find_rows2(csv_file2, search_word):
    """Ищет строки в CSV, где 4-й столбец содержит search_word"""
    matched_rows2 = []
    with open(csv_file2, newline='', encoding='utf-8') as file:
        reader = csv.reader(file, delimiter=';')  # Укажите нужный разделитель
        for row in reader:
            if search_word.lower() == row[0].lower():
                matched_rows2.append(row)
    return matched_rows2

def set_column_widths(table, data):
    """Устанавливает ширину колонок на основе максимальной длины текста"""
    col_widths = [max(len(str(row[i])) for row in data) for i in range(len(data[0]))]  

    for i, width in enumerate(col_widths):
        for cell in table.columns[i].cells:
            cell.width = Cm(width * 0.2)  # Настройка ширины, можно подкорректировать


# Функция для проверки, начинается ли строка с числа
def starts_with_number(s):
    return bool(re.match(r'^\d', s))

def set_cell_text(cell, text, font_size, align):
    paragraph = cell.paragraphs[0]
    run = paragraph.add_run(text)
    run.font.name = "Calibri"
    run.font.size = Pt(font_size)
    paragraph.alignment = align
    paragraph.paragraph_format.space_after = Pt(0)

def create_docx_from_csv(csv_path, search_word, output_path):
    """Создаёт новый DOCX с таблицей на основе данных из CSV"""
    rows = find_rows(csv_path, search_word)
    if not rows:
        print("Совпадений не найдено.")
        return
    
    unique = {}
    for i in range(40):
        unique[i] = set(row[i] for row in rows)  # Собираем уникальные значения

    #напряжение
    angl_string = ",".join(unique[11])
    volts_string = ",".join(unique[10]).replace(" ", "")
    filtered_volts = set(volts_string.split(","))
    sorted_volts = sorted(filtered_volts, key=lambda x: int(x.rstrip('V')))

    first_name = ", ".join(unique[3])

    #цветтовая температура
    TW_string = ",".join(unique[23])
    ct_string = ",".join(unique[12]).replace(" ", "")
    filtered_ct = set(ct_string.split(","))
    sorted_ct = sorted(filtered_ct, key=lambda x: (not starts_with_number(x), x))
    ct = ", ".join(sorted_ct)
    tw = ",".join(unique[23]).replace("TW", ", Tunable White")
    cttw = f"{ct}{tw}"

    #вес/масса
    weight_values = {float(x) for x in unique[13]}
    min_weight = min(weight_values)
    max_weight = max(weight_values)
    weightdot = f"{min_weight} кг" if min_weight == max_weight else f"{min_weight} − {max_weight} кг"
    weight = weightdot.replace(".", ",")

    material = ", ".join(unique[15])

    #система управления
    system_string = ",".join(unique[17]).replace(" ", "")
    filtered_system = set(system_string.split(","))

    priority = {
    'On/Off': 0,
    'PWM': 1,
    '0-10V': 2,
    '1-10V': 1,
    'DALI': 3,
    'DMX-512': 4,
    'RDM': 5
    }

    sorted_system = sorted(filtered_system, key=lambda x: (priority.get(x, 2), x))
    sys = ", ".join(sorted_system).replace("external", "внешний блок питания")

    cri = ", ".join(unique[19])
    ip = ", ".join(unique[21])
    ik = ", ".join(unique[22])
    q1 = ", ".join(unique[25])
    a1 = ", ".join(unique[27])
    q2 = ", ".join(unique[29])
    a2 = ", ".join(unique[31])
    q3 = ", ".join(unique[33])
    a3 = ", ".join(unique[35])
    q4 = ", ".join(unique[37])
    a4 = ", ".join(unique[39])

    # Папка, где лежат изображения
    image_folder = './pics'  # Путь можно поменять

    # Соответствия условий и изображений
    conditions = [
    ('220V' in filtered_volts, 'PE.jpg'),
    ('RGB' in filtered_ct, 'RGB.jpg'),
    ('RGBW' in filtered_ct, 'RGBW.jpg'),
    ('TW' in TW_string, 'TW.jpg'),
    ('RGBCLA' in filtered_ct, 'CLA.jpg'),
    ('DMX-512' in filtered_system, 'DMX.jpg'),
    ('DALI' in filtered_system, 'DALI.jpg'),
    ('0-10V' in filtered_system, '010.jpg'),
    ('1-10V' in filtered_system, '110.jpg'),
    ('RDM' in filtered_system, 'RDM.jpg'),
    ('65' in ip, 'IP65.jpg'),
    ('66' in ip, 'IP66.jpg'),
    ('67' in ip, 'IP67.jpg'),
    ('68' in ip, 'IP68.jpg'),
    ('IK08' in ik, 'IK08.jpg'),
    ('IK09' in ik, 'IK09.jpg'),
    ('IK10' in ik, 'IK10.jpg'),                     
    ('−' in angl_string, 'zoom.jpg')
    ]

    images_to_add = ['CE.jpg', 'F.jpg', 'LED.jpg']

    color_mapping = {
    "Black": "Черный",
    "Grey": "Серый",
    "White": "Белый",
    "Metallic": "Металлик",
    "Silver": "Серебро",
    "Steel": "Сталь",
    "Mirrored steel": "Глянцевая сталь",
    "Brushed steel": "Матовая сталь",
    "Steel": "Металлик",
    "Brown": "Серый",
    "Red": "Красный",
    "Ochre": "Охра"
    }
    input_list = unique[16].pop().split(', ')
    # Применяем соответствия из словаря
    output_string = ', '.join([color_mapping.get(color, color) for color in input_list])

    # Определяем переменные
    if "220V" in sorted_volts:
        volts220 = "220\u00A0В"
        voltslow = sorted_volts.remove("220V")
    else:
        volts220 = None

    voltslow = "/".join(sorted_volts).replace("V", "\u00A0В") if sorted_volts else None

    doc = docx.Document()
    set_landscape(doc)  # Устанавливаем альбомную ориентацию
    set_two_columns(doc)  # Разделяем на две колонки

    cable220dmx = None
    cablelowdmx = None
    cable220 = f"{volts220}: 3×0,75 мм²" if volts220 else None
    if cable220 is None:
        cablelow = f"{voltslow}: 2×1 мм²" if voltslow else None
    else:
        cablelow = f"\n{voltslow}: 2×1 мм²" if voltslow else None

    for row in rows:
        if len(row) > 6:  # Проверяем, есть ли 7-й элемент (индекс 6)
            words = row[5].split()  # Разбиваем 6-й элемент строки на слова
            if "RGB" in words or "RGВW" in words:
                if "220V" in words:
                    cable220dmx = ", DMX-512: 3×0,5 мм²"
                elif "24V/220V" in words:
                    cable220dmx = " (DMX-512: 3×0,5 мм²)"
                    cablelowdmx = f" ({voltslow} + DMX-512: 5×0,5 мм²)"
                else:
                    cablelowdmx = f" ({voltslow} + DMX-512: 5×0,5 мм²)"
    
    cable = " ".join(filter(None, [cable220, cable220dmx, cablelow, cablelowdmx]))

    csv_path3 = 'pass.csv'
    rows3 = find_rows2(csv_path3, search_word)
    if not rows3:
        print(f"Нет данных в pass.csv для {search_word}")
        return
    descript = rows3[0][1]
    instruct = rows3[0][2]

    logo = doc.add_paragraph("\n")
    par_logo = logo.add_run()
    par_logo.add_picture("logoimg.jpg", width=Cm(4.5))  # Можно указать размеры
    logo.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
    title0 = doc.add_paragraph()
    title0.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    name0 = title0.add_run("\nСВЕТОДИОДНЫЙ СВЕТИЛЬНИК\n")
    name1 = title0.add_run(f"{rows[0][3]}\n")
    name1.bold = True
    name2 = title0.add_run(" ПАСПОРТ ПРОДУКТА\n")
    par1 = doc.add_paragraph(f"1. НАЗНАЧЕНИЕ\n")
    par1.add_run(f"1.1. {descript}.\n")
    par1.add_run(f"1.2. Изделие соответствует требованиям безопасности ЭМС ГОСТ 51318-99.\n")
    par1.add_run(f"1.3. Изделие может использоваться как для наружной установки, так и внутри помещений.")
    par2 = doc.add_paragraph(f"2. ТЕХНИЧЕСКИЕ ХАРАКТЕРИСТИКИ\n")
    par2.add_run(f"2.1. Таблица 1.")

    # Создаём таблицу1
    table = doc.add_table(rows=1, cols=7)
    table.style = "Table Grid"

    # Заголовки столбцов
    hdr_titles = ["Артикул", "Наименование", "Размер, мм", "Вес, кг", "Потребл. мощность", "Вход. напряжение", "Угол рассеивания"]
    hdr_cells = table.rows[0].cells
    for i, title in enumerate(hdr_titles):
        hdr_cells[i].text = title
        hdr_cells[i].paragraphs[0].runs[0].font.name = "Calibri"
        hdr_cells[i].paragraphs[0].runs[0].font.size = Pt(6)

    # Заполняем таблицу и собираем данные
    data = []  # Список для хранения строк данных
    for row in rows:
        data_row = [row[1], row[6], row[9], row[13], row[8].replace("W", "Вт"), row[10].replace(" V", "\u00A0В"), row[11].replace("diffused", "(рассеянный)").replace("beams", "(луча)")]  # Берём нужные столбцы
        data.append(data_row) # Добавляем в список
        tbl_row = table.add_row().cells
        
        for i, value in enumerate(data_row):
            para = tbl_row[i].paragraphs[0]
            run = para.add_run()
            
            run.text = str(value)
            run.font.name = "Calibri"
            run.font.size = Pt(6)
            
    # Устанавливаем автоширину колонок
    set_column_widths(table, data)
    cri_tab = None

    #if cri not in [None, "", 0]:  # Проверяем, что cri НЕ пустой и НЕ 0
    if cri == 0 or cri == None or cri == "":  # Проверяем, что cri НЕ пустой и НЕ 0
        cri_tab = f"CRI >{cri}"
    else: cri_tab = None

    # Данные (переменная: значение)
    data2 = {
        "Корпус:": material,
        "Цвет корпуса:": output_string,
        "Механическая защита корпуса:": ik,
        "Цветовая температура:": cttw,
        "Индекс цветопередачи:": cri_tab,
        "Коэффициент мощности:": ">0.9",
        "Система управления:": sys,
        q1: a1,
        q2: a2,
        q3: a3,
        q4: a4,
        "Рабочая температура:": "−40⁰ ~ +50⁰ (при запуске −20⁰ ~ +45⁰)",
        "Ресурс работы светильника:": "не менее 50 000 ч",
        "Cечение проводов:": cable,
        "Вес:": weight
    }

    doc.add_paragraph("\u00A0")
    Tables2 = doc.add_paragraph()
    #Tables2.paragraph_format.first_line_indent = Cm(1)
    Tables2.add_run(f"2.1. ОБЩИЕ ХАРАКТЕРИСТИКИ")
    # Создаём таблицу (колонки: Название, Значение)
    table2 = doc.add_table(rows=0, cols=2)
    table2.style = "Table Grid"
    table2.autofit = True

    # Добавляем строки только с непустыми значениями
    for key, value in data2.items():
        if value:  # Проверяем, что значение не None и не пустая строка
            row2_cells = table2.add_row().cells
            row2_cells[0].text = key  # Название параметра
            row2_cells[1].text = str(value)  # Значение

            row2_cells[0].width = Cm(5.5)

            # Применяем шрифт Times New Roman 8pt ко всем ячейкам строки
            for cell in row2_cells:
                for paragraph in cell.paragraphs:
                    for run in paragraph.runs:
                        run.font.name = "Calibri"
                        run.font.size = Pt(8)

    par_pics = doc.add_paragraph("\n")
    par_pics.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

    # Добавляем изображения по условиям

    for condition, filename in conditions:
        if condition:
            images_to_add.append(filename)

    first = True
    for filename in images_to_add:
        image_path = os.path.join(image_folder, filename)
        if os.path.exists(image_path):
            if not first:
                # Добавляем отступ между картинками: "пустой" пробел шириной 0.3 см
                spacer = par_pics.add_run("\u00A0")
                #spacer.font.size = Cm(0.5)  # Невидимый пробел
            run = par_pics.add_run()
            run.add_picture(image_path, width=Cm(0.8))  # Размер 1 см
            first = False
        else:
            print(f"Пропущен файл: {filename} — он отсутствует или невалиден.")

    liner_folder = os.path.join('.', 'drafts', first_name)

    csv_path2 = 'desc_eng.csv'
    rows2 = find_rows2(csv_path2, search_word)

    # Получаем список изображений с числами в имени
    supported_exts = ['.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff']
    liner_images = []
    for fname in os.listdir(liner_folder):
        if Path(fname).suffix.lower() in supported_exts:
            match = re.search(r'(\d+)', fname)
            if match:
                order = int(match.group(1))
                liner_images.append((order, fname))

    # Сортируем изображения по числу
    liner_images.sort(key=lambda x: x[0])

 # Строим таблицу
    if liner_images:
        num_images = len(liner_images)
        num_cols = 2
        num_rows = ceil(num_images / num_cols)

        table3 = doc.add_table(rows=num_rows, cols=num_cols)
        table3.style = "Table Grid"
        table3.autofit = True

        img_index = 0
        for row in range(num_rows):
            # Проверка: последняя строка и нечётное число изображений
            is_last_row = (row == num_rows - 1)
            is_odd = (num_images % 2 != 0)
            one_image = (num_images == 1)

            if (is_last_row and is_odd) or one_image:
                # Объединяем ячейки в строке
                cell = table3.cell(row, 0).merge(table3.cell(row, 1))
                
                if img_index < num_images:
                    order, img_filename = liner_images[img_index]
                    img_path = os.path.join(liner_folder, img_filename)

                    # Вставка картинки
                    pic_paragraph = cell.paragraphs[0]
                    pic_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                    pic_run = pic_paragraph.add_run()
                    pic_run.add_picture(img_path, width=Cm(6))
                    pic_paragraph.paragraph_format.space_after = Pt(0)

                    # Подпись
                    raw_caption = rows2[0][img_index + 1]
                    caption = first_name if raw_caption == "0" else raw_caption
                    caption_paragraph = cell.add_paragraph(caption)
                    caption_paragraph.paragraph_format.space_after = Pt(0)
                    caption_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                    caption_run = caption_paragraph.runs[0]
                    caption_run.font.size = Pt(7)
                    caption_run.font.name = "Calibri"

                    img_index += 1
            else:
                # Стандартная вставка для строки из 2 изображений
                for col in range(num_cols):
                    cell = table3.cell(row, col)
                    if img_index < num_images:
                        order, img_filename = liner_images[img_index]
                        img_path = os.path.join(liner_folder, img_filename)

                        # Вставка картинки
                        pic_paragraph = cell.paragraphs[0]
                        pic_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                        pic_run = pic_paragraph.add_run()
                        pic_run.add_picture(img_path, width=Cm(6))
                        pic_paragraph.paragraph_format.space_after = Pt(0)

                        # Подпись
                        raw_caption = rows2[0][img_index + 1]
                        caption = first if raw_caption == "0" else raw_caption
                        caption_paragraph = cell.add_paragraph(caption)
                        caption_paragraph.paragraph_format.space_after = Pt(0)
                        caption_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                        caption_run = caption_paragraph.runs[0]
                        caption_run.font.size = Pt(7)
                        caption_run.font.name = "Calibri"

                        img_index += 1
                    else:
                        cell.text = ''
    doc.add_paragraph(f"\n3. КОМПЛЕКТ ПОСТАВКИ")
    table_t1 = doc.add_table(rows=3, cols=2)
    table_t1.autofit = False

    col_widths1 = [Cm(2.5), Cm(2)]

    for row_t1 in table_t1.rows:
        row_t1.height = Pt(1)  # минимально возможное значение (можно 0.1, но Word округлит)
        for idx, cell in enumerate(row_t1.cells):
            if idx < len(col_widths1):
                cell.width = col_widths1[idx]

    set_cell_text(table_t1.rows[0].cells[0], f"Светильник, шт.", font_size=8, align=WD_PARAGRAPH_ALIGNMENT.LEFT)
    set_cell_text(table_t1.rows[0].cells[1], f"1", font_size=8, align=WD_PARAGRAPH_ALIGNMENT.LEFT)
    set_cell_text(table_t1.rows[1].cells[0], f"Упаковка, шт. ", font_size=8, align=WD_PARAGRAPH_ALIGNMENT.LEFT)
    set_cell_text(table_t1.rows[1].cells[1], f"1", font_size=8, align=WD_PARAGRAPH_ALIGNMENT.LEFT)
    set_cell_text(table_t1.rows[2].cells[0], f"Паспорт, шт.", font_size=8, align=WD_PARAGRAPH_ALIGNMENT.LEFT)
    set_cell_text(table_t1.rows[2].cells[1], f"1", font_size=8, align=WD_PARAGRAPH_ALIGNMENT.LEFT)

    par4 = doc.add_paragraph(f"\n4. УКАЗАНИЕ МЕР БЕЗОПАСНОСТИ\n")
    par4.add_run(f"4.1. Присоединение, отсоединение изделия от сети, коммутацию с управляющим оборудованием производить только при отключенном питании.\n")
    par4.add_run(f"4.2. Не допускается эксплуатация изделий с повреждениями изоляции проводов и мест электрических соединений.\n")
    par4.add_run(f"4.3. Светильник может быть установлен на поверхности из нормально воспламеняемого материала.")
    par5= doc.add_paragraph(f"5. ПРАВИЛА ЭКСПЛУАТАЦИИ И ТЕХНИЧЕСКОЕ ОБСЛУЖИВАНИЕ\n")
    par5.add_run(f"5.1. Эксплуатация изделия производится в соответствие с «Правилами технической эксплуатации электроустановок потребителей».\n")   
    par5.add_run(f"5.2. {instruct}.\n")   
    par5.add_run(f"5.3. В процессе эксплуатации изделия необходимо не реже двух раз в год проводить профилактический осмотр и чистку изделия. Проверить исправность электроустановочных изделий и надежность крепления болтовых и винтовых соединений. Чистку защитного стекла и корпуса изделия производить мягкой ветошью, смоченной в мыльном растворе.\n")   
    par5.add_run(f"5.4. Эксплуатация изделия с треснувшим или иначе поврежденным защитным стеклом или корпусом не допускается, поврежденные элементы необходимо заменить.")   
    par6= doc.add_paragraph(f"6. СВИДЕТЕЛЬСТВО О ПРИЕМКЕ\n")
    par6.add_run(f"Светильник {first_name} соответствует требованиям ТУ 3461-006-44919750-07 и признан годным к эксплуатации.")
    par7 = doc.add_paragraph(f"7. ГАРАНТИЙНЫЕ ОБЯЗАТЕЛЬСТВА\n")
    par7.add_run(f"7.1. Гарантийный срок эксплуатации изделия составляет 60 месяцев со дня ввода в эксплуатацию, но не позднее 60 месяцев со дня поступления к потребителю.\n")
    par7.add_run(f"7.2. В случае обнаружения неисправности изделия до истечения гарантийного срока необходимо обратиться к представителю завода-изготовителя в РФ по адресу:\nРоссия, 125067, г. Москва, Проезд Аэропорта, 8.")
    par8 = doc.add_paragraph(f"8. СВЕДЕНИЯ ОБ УПАКОВКЕ, ТРАНСПОРТИРОВАНИИ И ХРАНЕНИИ\n")
    par8.add_run(f"8.1. Упаковка изделия соответствует ГОСТ23216-78.\n")    
    par8.add_run(f"8.2. Транспортирование изделий должно производиться в контейнерах, закрытым автотранспортом и в крытых железнодорожных вагонах в соответствии с ГОСТ23216-78.\n")
    par8.add_run(f"8.3. Условия хранения: навесы или помещения, где колебания температуры и влажности воздуха несущественно отличаются от колебаний на открытом воздухе.\nТемпература воздуха: от минус 50°С до плюс 50°С.\nВерхнее значение относительной влажности воздуха 100% при 25°С.\n")
    par8.add_run(f"8.4. Изделия хранят уложенными на стеллажи или поддоны в штабели высотой не более 1,65 м. Хранение должно обеспечивать их сохранность от механических повреждений.")  
    par9 = doc.add_paragraph(f"9. УТИЛИЗАЦИЯ\n")
    par9.add_run(f"9.1. При истечении срока службы изделия разобрать на детали, рассортировать по видам материалов и сдать в специализированные организации по приемке и переработке вторсырья.\n")        

    for para in doc.paragraphs:
    # Устанавливаем отступ первой строки (1 см)
        para.paragraph_format.space_after = Pt(6)
        # Устанавливаем межстрочный интервал (1.5)
        para.paragraph_format.line_spacing = 1.15
        for run in para.runs:
            run.font.size = Pt(8)
            run.font.name = "Calibri"


    name0.font.size = Pt(14)
    name1.font.size = Pt(14)
    name2.font.size = Pt(14)

    doc.core_properties.author = "IMG"
    doc_name = f"{first_name} паспорт.docx"
    doc.save(doc_name)


    print(f"Документ сохранён как {doc_name}")
    os.startfile(doc_name)

# Использование
csv_file = "data.csv"  # Укажите путь к CSV
search_word = input("Введите слово для поиска: ")
output_file = "паспорт.docx"

create_docx_from_csv(csv_file, search_word, output_file)