<template>
  <div class="pblm-detail-wrapper">
    <van-form @submit="onSubmit">
      <div class="pblm-detail-label">
        <span>问题详情</span>
        <!-- <van-button size="mini" type="primary" @click="showTacObjPblmstbPopup()">选择违规事项</van-button> -->
      </div>
      <van-cell-group inset>
        <van-field v-model="tacObjPblmstb.nm" placeholder="请输入对象名称" label="对象名称" />
        <van-field
            v-model="tacObjPblmstb.inspPblmsName"
            is-link
            readonly
            label="问题类别"
            placeholder="选择对象"
            @click="showPicker = true"
        />
        <van-popup v-model:show="showPicker" destroy-on-close round position="bottom">
            <van-picker
            :columns="columns"
            @change="changeC1"
            @cancel="showPicker = false"
            @confirm="onConfirm"
            />
        </van-popup>
        <van-field
            v-model="tacObjPblmstb.checkPoint"
            is-link
            readonly
            label="问题项目"
            placeholder="选择对象"
            @click="showPicker1 = true"
        />
        <van-popup v-model:show="showPicker1" destroy-on-close round position="bottom">
            <van-picker
            :columns="columns1"
            @change="changeC2"
            @cancel="showPicker1 = false"
            @confirm="onConfirm1"
            />
        </van-popup>
        <van-field
            v-model="tacObjPblmstb.pblmDesc"
            is-link
            readonly
            label="问题描述"
            placeholder="选择对象"
            @click="showPicker2 = true"
        />
        <van-popup v-model:show="showPicker2" destroy-on-close round position="bottom">
            <van-picker
            :columns="columns2"
            @cancel="showPicker2 = false"
            @confirm="onConfirm2"
            />
        </van-popup>
        <van-field v-model="tacObjPblmstb.inspPblmOrgName" placeholder="请输入对象名称" label="问题责任单位" />
        <van-field v-model="tacObjPblmstb.inspPblmDesc" placeholder="请输入对象名称" label="详细描述" rows="1" type="textarea"/>
        <van-field
            v-model="tacObjPblmstb.ifCasePblm"
            is-link
            readonly
            label="是否典型问题"
            placeholder=""
            @click="showPicker3 = true"
        />
        <van-popup v-model:show="showPicker3" destroy-on-close round position="bottom">
            <van-picker
            :columns="columns3"
            :model-value="pickerValue3"
            @cancel="showPicker3 = false"
            @confirm="onConfirm3"
            />
        </van-popup>
        <van-field v-model="tacObjPblmstb.score" readonly label="扣分值" />
        <van-field v-model="tacObjPblmstb.persName" readonly label="上报人" />
        <van-field v-model="tacObjPblmstb.collTime" readonly label="上报时间" />
        <div style="display: flex;align-items: center;margin-top: -1%;">
            <div style="width: 20%;text-align: center;font-weight: 700;font-size: 14px;">上传照片</div>
            <van-uploader v-model="fileList" :after-read="afterRead" style=""/>
        </div>
      </van-cell-group>
      <div style="margin: 16px;">
        <van-button v-if="objData.state !== '2'" @click="save"  block native-type="submit" round type="primary">
          保存问题
        </van-button>
      </div>
    </van-form>

    <van-popup v-model:show="tacObjPblmstbShow" :style="{ width: '80%', height: '100%' }" position="left">
      <tacObjPblmstbList :listType="pblm.listType" style="z-index:3000;"
                         @change="changeTacObjPblmstb"></tacObjPblmstbList>
    </van-popup>
  </div>
</template>
<script setup>
import { showSuccessToast, showFailToast } from 'vant';
import {computed, onMounted, ref, watch} from "vue";
import {useRoute,useRouter} from "vue-router";
import { getToken } from "@/utils/auth";
import { useAppStore } from '@/stores/app';
import {useUserStore} from "@/stores/user";
import tacObjPblmstbList from './TacObjPblmstbList.vue';
import {getTacQuestionById} from "@/api/inspect";
import { showConfirmDialog } from 'vant';
import {addTacQuestion, getIllegalActById, getTacUnitList} from "@/api/questions";
import request from "@/utils/request";
const route = useRoute();
const router1 = useRouter();
const userStore = useUserStore();
const fileList = ref([]);
const listType = ref(route.query.inspectType || '1');
const pblm = ref({});
const tacObjPblmstb =  ref({
});
const url = process.env.VUE_APP_BASE_API
const columns = ref([]);
const columns1 = ref([]);
const columns2 = ref([]);
const columns3 = ref([
    { text: '是', value: '1' },
    { text: '否', value: '0' }
]);
const showPicker = ref(false);
const showPicker1 = ref(false);
const showPicker2 = ref(false);
const showPicker3 = ref(false);
const pickerValue3 = ref([])
const pickerValue = ref([])
const pickerValue1 = ref([])
const pickerValue2 = ref([])
const router = useRoute();
const parSectino = ref([]);
const subjectList = ref([]);
const tacObjPblmstbShow = ref(false);
const accessToken = localStorage.getItem('accessToken') || '';
function onConfirm3(selectedValues, selectedOptions) {
  tacObjPblmstb.value.ifCasePblm = selectedValues.selectedOptions[0].text
  showPicker3.value = false;
}
function onConfirm(selectedValues, selectedOptions) {
  tacObjPblmstb.value.inspPblmsName = selectedValues.selectedOptions[0].text
  showPicker.value = false;
}
function onConfirm1(selectedValues, selectedOptions) {
  tacObjPblmstb.value.checkPoint = selectedValues.selectedOptions[0].text
  showPicker1.value = false;
}
function onConfirm2(selectedValues, selectedOptions) {
  tacObjPblmstb.value.pblmDesc = selectedValues.selectedOptions[0].text
  showPicker2.value = false;
}
function changeC1(selectedValues, selectedOptions) {
  columns1.value = []
  columns2.value = []
  parSectino.value.forEach(item => {
    if(item.inspPblmsName === selectedValues.selectedValues[0]){
        var par = {
            text: item.checkPoint,
            value: item.checkPoint
        }
        columns1.value.push(par);
    }
    columns1.value = [...new Set(columns1.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
  })
}
function changeC2(selectedValues, selectedOptions) {
  columns2.value = []
  parSectino.value.forEach(item => {
    if(item.checkPoint === selectedValues.selectedValues[0]){
        var par = {
            text: item.pblmDesc,
            value: item.pblmDesc
        }
        columns2.value.push(par);
    }
    columns2.value = [...new Set(columns2.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
  })
  console.log(columns1.value)
}
function formatTime(timestamp) {
  const date = new Date(timestamp);
  const year = date.getFullYear();
  const month = ('0' + (date.getMonth() + 1)).slice(-2);
  const day = ('0' + date.getDate()).slice(-2);
  const hours = ('0' + date.getHours()).slice(-2);
  const minutes = ('0' + date.getMinutes()).slice(-2);
  const seconds = ('0' + date.getSeconds()).slice(-2);

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
async function getSelection(){
    await request.get(`/dc/insp/pblms/listByObjId/${pblm.value.objId}`).then(res=>{
        parSectino.value = res.data
        const uniqueInspPblmsName = [...new Set(res.data.map(item => item.inspPblmsName))];
        const uniquePblmDesc = [...new Set(res.data.map(item => item.pblmDesc))];
        const uniqueCheckPoint = [...new Set(res.data.map(item => item.checkPoint))];
        // columns1.value = uniqueCheckPoint.map(item => ({ text: item, value: item }));
        // columns2.value = uniquePblmDesc.map(item => ({ text: item, value: item }));
        columns.value = uniqueInspPblmsName.map(item => ({ text: item, value: item }));
    })
}
const parData = ref({});
function getDe(){
    request.get(`/dc/insp/pblm/${pblm.value.pblmId}`).then(res=>{
        if(res.success){
            parData.value = res.data
            tacObjPblmstb.value = res.data;
            tacObjPblmstb.value.ifCasePblm = tacObjPblmstb.value.ifCasePblm === '1' ? '是' : '否';
            tacObjPblmstb.value.collTime = formatTime(tacObjPblmstb.value.collTime);
            columns1.value = []
            columns2.value = []
            parSectino.value.forEach(item => {
                if(item.inspPblmsName === tacObjPblmstb.value.inspPblmsName){
                    console.log(item);
                    var par = {
                        text: item.checkPoint,
                        value: item.checkPoint
                    }
                    columns1.value.push(par);
                }
                columns1.value = [...new Set(columns1.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
            })
            parSectino.value.forEach(item => {
                if(item.checkPoint === tacObjPblmstb.value.checkPoint){
                    console.log(item);
                    var par = {
                        text: item.pblmDesc,
                        value: item.pblmDesc
                    }
                    columns2.value.push(par);
                }
                columns2.value = [...new Set(columns2.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
            })
            res.data.gwComFiles.forEach(item => {
                item.filePath = item.filePath.replace(/\\/g, '/');
                fileList.value.push({
                    url: url + item.filePath,
                    name: item.fileName,
                    isImage: true,
                    id: item.id
                })
                console.log(fileList.value);
            })
        }
    })
}
// 获取需要认证的图片并转换为 base64
async function getAuthImageAsBase64(imageUrl) {
    try {
        // 1. 使用 fetch 请求图片，携带 token
        const response = await fetch(imageUrl, {
            headers: {
                'Authorization': `Bearer ${localStorage.getItem('token')}`,
                'X-Token': localStorage.getItem('token') // 根据实际情况调整
            }
        });

        if (!response.ok) {
            throw new Error(`HTTP错误: ${response.status}`);
        }

        // 2. 获取图片的 ArrayBuffer
        const arrayBuffer = await response.arrayBuffer();

        // 3. 转换为 base64
        const base64 = btoa(
            new Uint8Array(arrayBuffer).reduce(
                (data, byte) => data + String.fromCharCode(byte),
                ''
            )
        );

        // 4. 根据图片类型生成 data URL
        const contentType = response.headers.get('content-type') || 'image/png';
        return `data:${contentType};base64,${base64}`;

    } catch (error) {
        console.error('获取认证图片失败:', error);
        throw error;
    }
}
async function save(){
    console.log(tacObjPblmstb.value);
    tacObjPblmstb.value.ifCasePblm = tacObjPblmstb.value.ifCasePblm === '是' ? '1' : '0';
    // tacObjPblmstb.value.collTime = parData.value.collTime;
    delete tacObjPblmstb.value.inspPblmCode;
    delete tacObjPblmstb.value.pblmsTypeId;
    delete tacObjPblmstb.value.collTime;
    // uploadFileToServer(newFile.value, parData.value.pblmId)
    await request.post('/dc/insp/pblm/update', tacObjPblmstb.value).then((res) => {
        if (res.success) {
            fileList.value.forEach(item => {
                console.log(item)   
                if(!item.id){
                    uploadFileToServer(item, parData.value.pblmId)
                }
            })
            showSuccessToast('保存成功!');
            router1.go(-1)
            fileList.value = []
        }
    });
    getDe();
}
watch(() => tacObjPblmstb.value.inspPblmsName, (newVal, oldVal) => {
    if (newVal !== oldVal) {
        columns1.value = []
        columns2.value = []
        parSectino.value.forEach(item => {
            if(item.inspPblmsName === newVal){
                var par = {
                    text: item.checkPoint,
                    value: item.checkPoint
                }
                columns1.value.push(par);
            }
            columns1.value = [...new Set(columns1.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
        })
    }
});
watch(() => tacObjPblmstb.value.checkPoint, (newVal, oldVal) => {
    if (newVal !== oldVal) {
        columns2.value = []
        parSectino.value.forEach(item => {
            if(item.checkPoint === newVal){
                var par = {
                    text: item.pblmDesc,
                    value: item.pblmDesc
                }
                columns2.value.push(par);
            }
            columns2.value = [...new Set(columns2.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
        })
    }
});
function getObjectArrayDiff(arr1, arr2, key) {
  if (!key) throw new Error('必须指定对比的唯一字段（如id）');

  // 提取两个数组的key值集合
  const keySet1 = new Set(arr1.map(item => item[key]));
  const keySet2 = new Set(arr2.map(item => item[key]));

  // 仅在arr1中存在的对象
  const onlyInArr1 = arr1.filter(item => !keySet2.has(item[key]));
  // 仅在arr2中存在的对象
  const onlyInArr2 = arr2.filter(item => !keySet1.has(item[key]));
  // 所有差异对象（合并）
  const allDiff = [...onlyInArr1, ...onlyInArr2];

  return {
    onlyInArr1,
    onlyInArr2,
    allDiff
  };
}
const dataURLtoBlob = (dataURL) => {
  try {
    const arr = dataURL.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
  } catch (e) {
    console.error('base64转Blob失败:', e);
    return new Blob([], { type: 'application/octet-stream' });
  }
};

// 2. 手动构建multipart/form-data（保留之前验证正确的逻辑）
const buildMultipartFormData = async (file) => {
  if (!file) throw new Error('文件为空');

  // 生成标准boundary
  const boundary = `----WebKitFormBoundary${Math.random().toString(36).substr(2, 16)}`;

  // 处理文件为Blob
  let fileBlob;
  if (file.content instanceof Blob || file.content instanceof File) {
    fileBlob = file.content;
  } else if (typeof file.content === 'string' && file.content.startsWith('data:')) {
    fileBlob = dataURLtoBlob(file.content);
  } else {
    throw new Error(`不支持的文件格式: ${typeof file.content}`);
  }

  // 读取文件为ArrayBuffer
  const fileBuffer = await new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsArrayBuffer(fileBlob);
  });

  // 手动拼接multipart格式（字符串转Uint8Array，兼容App端）
  const stringToUint8Array = (str) => {
    const arr = [];
    for (let i = 0; i < str.length; i++) {
      arr.push(str.charCodeAt(i));
    }
    return new Uint8Array(arr);
  };

  const parts = [];
  // 拼接分隔符+元信息
  parts.push(stringToUint8Array(`--${boundary}\r\n`));
  parts.push(stringToUint8Array(`Content-Disposition: form-data; name="file"; filename="${encodeURIComponent(file.name || 'upload.png')}"\r\n`));
  parts.push(stringToUint8Array(`Content-Type: ${fileBlob.type || 'application/octet-stream'}\r\n\r\n`));
  // 拼接文件二进制数据
  parts.push(new Uint8Array(fileBuffer));
  // 拼接结束分隔符
  parts.push(stringToUint8Array(`\r\n--${boundary}--\r\n`));

  // 合并所有片段
  const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
  const resultBuffer = new Uint8Array(totalLength);
  let offset = 0;
  parts.forEach(part => {
    resultBuffer.set(part, offset);
    offset += part.length;
  });

  return {
    body: resultBuffer,
    contentType: `multipart/form-data; boundary=${boundary}`
  };
};

// 3. 核心：改用Fetch API上传文件（替换Axios）
const uploadFileToServer = async (file, bizId) => {
  if (!file || !bizId) {
    showFailToast('文件或业务ID为空');
    return null;
  }

  try {
    // 构建标准multipart请求体
    const { body, contentType } = await buildMultipartFormData(file);

    // 获取token和自定义头（和Axios拦截器一致）
    const appStore = useAppStore();
    const userStore = useUserStore();
    const token = getToken();

    // 拼接完整接口地址（补充baseURL，和你的request封装一致）
    const baseURL = process.env.VUE_APP_BASE_API;
    const fullUrl = `${baseURL}/file/insert?bizId=${bizId}`;

    // 使用Fetch API发送请求（原生支持二进制，无兼容性问题）
    const formData = new FormData();
    formData.append('file', fileList.value[0].content); // 文件参数
    const response = await fetch(fullUrl, {
      method: 'POST',
      headers: {
        'Content-Type': contentType, // 带boundary的标准格式
        'Accept': 'application/json',
        'Persid': userStore.userId,
        'Accesstoken': token,
        'Cache-Control': 'no-cache'
      },
      body: new Blob([body], { type: contentType }), // 二进制请求体
      timeout: 30000,
      credentials: 'include' // 保持cookie/token会话（和Axios一致）
    });

    // 解析响应
    if (!response.ok) {
      throw new Error(`请求失败: ${response.status}`);
    }
    const resData = await response.json();
    console.log('文件上传成功:', resData);
    return resData;

  } catch (error) {
    console.error('文件上传失败:', error);
    showFailToast('文件上传失败');
    throw error;
  }
};
// /pdcApi/file
const newFile = ref({})
const isAdding = ref(false);
watch(() => fileList.value, (newVal, oldVal) => {
    if (newVal.length>oldVal.length && objData.value.state !== '2') {
        isAdding.value = true;
        newFile.value = getObjectArrayDiff(newVal, oldVal, 'id').onlyInArr1[0]
        console.log(newFile.value);

    }
    else if(newVal.length<oldVal.length&&newVal.length>0 && objData.value.state !== '2'){
        isAdding.value = false;
        newFile.value = getObjectArrayDiff(newVal, oldVal, 'id').onlyInArr2[0];
        showConfirmDialog({
        title: '删除',
        message:
            '是否确认删除',
        })
        .then(() => {
            request.post(`/file/${newFile.value.id}`).then(res=>{
                if(res.success){
                    showSuccessToast('删除成功!');
                }
            })
        })
        .catch(() => {
            fileList.value = oldVal;
        });
            }
});
const objData = ref({});
onMounted(() => {
  var par = JSON.parse(router.query.object);
  objData.value = par;
  objData.value.state = route.params.id
  console.log(objData.value);
  pblm.value.objId = par.objId
  pblm.value.pblmId = par.pblmId;
  getSelection().then(() => {
    getDe();
  })
})

</script>
<style lang="scss" scoped>
.pblm-detail-wrapper {
  height: 120%;
  padding: 10px 0;
  overflow: auto;

  .pblm-detail-label {
    padding: 10px 16px;
    color: #606266;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

}
</style>
<style lang="scss">
.van-cell-group--inset {
  margin: 0 10px;
}
</style>
