<script lang="ts" setup>
import { useFormGroup } from '@idux/cdk'
import times, { FMT } from '@/common/utils/times.ts'
import {
  TableColumn,
  TableColumnSelectable
} from '@idux/components/table'
import { TablePagination } from '@idux/components/table/src/types'
import TspApi from '@/pages/tsp/tsp-api.ts'
import TspPhotoApi from '@/pages/tsp-photo/tsp-photo-api.ts'

const props = defineProps<{
  tspPhotoData: TspPhotoTypes.TspPhotoSearchParam
  status: 'edit' | 'view'
}>()

const emit = defineEmits([ 'update:tspPhotoData' ])

const weekday = [ '周一', '周二', '周三', '周四', '周五', '周六', '周日' ]
const days = ref<Array<Array<TspPhotoTypes.DayType | null>>>([])
const tspPhotoForm = useFormGroup<TspPhotoTypes.TspPhotoSearchParam>({
  tspId: [ '' ],
  pointName: [ '' ],
  month: [ new Date() ],
  day: [ new Date().getDate() ],
  uploadDate: [ times.format(new Date(), FMT.date) ],
})

const selectedRowKeys = ref<string[]>([])
const tableSpin = ref(false)
const datasource = ref<TspTypes.TspData[]>([])
const selectableColumn = reactive<TableColumnSelectable<TspTypes.TspData>>({
  type: 'selectable',
  align: 'center',
  multiple: false,
  showIndex: false,
  trigger: 'click',
  onChange: (selectedKeys) => {
    if (selectedKeys.length === 0) {
      const value = tspPhotoForm.get('tspId')?.getValue()
      if (value != null) {
        selectedRowKeys.value = [ value ]
      } else {
        tspPhotoForm.get('tspId')?.setValue('')
        tspPhotoForm.get('pointName')?.setValue('')
      }
      return
    }
    const data = datasource.value?.find(item => item.id === (selectedKeys[0] as string))
    tspPhotoForm.get('tspId')?.setValue(selectedKeys[0] as string)
    tspPhotoForm.get('pointName')?.setValue(data?.pointName)
  },
})
const columns: TableColumn<TspTypes.TspData>[] = [
  selectableColumn,
  {
    title: '名称',
    dataKey: 'pointName',
    customCell: 'pointName'
  },
  {
    title: '所属街道',
    dataKey: 'streetName',
  },
  {
    title: '所属小区',
    dataKey: 'microdistrict',
  },
  {
    title: '所属物业',
    dataKey: 'propertyManagement'
  },
]

function searchHandler() {
  tableSpin.value = true
  return TspApi.paging({
    current: pagination.pageIndex ?? 1,
    size: pagination.pageSize ?? 10,
  }).then(res => {
    pagination.pageIndex = res.data.current
    pagination.pageSize = res.data.size
    pagination.total = res.data.total
    datasource.value = res.data.records
    return res.data.records
  }).finally(() => {
    tableSpin.value = false
  })
}

const pagination = reactive<TablePagination>({
  pageIndex: 1,
  pageSize: 10,
  total: 0,
  size: 'sm',
  showTotal: true,
  onChange(pageIndex: number, pageSize: number) {
    pagination.pageIndex = pageIndex
    pagination.pageSize = pageSize
    searchHandler()
  }
})

const visible = ref(false)

function disabledDate(date: Date) {
  return times.parse(date).month > times.now().month
}

watch(visible, (newVal) => {
  if (newVal) {
    searchHandler()
  }
})

function selectDayHandler(day: TspPhotoTypes.DayType) {
  const date = `${day.year}-${day.month < 10 ? '0' + day.month : day.month}-${day.day < 10 ? '0' + day.day : day.day}`
  const dateObj = times.parse(date, FMT.date)
  if (dateObj.diffNow().toMillis() > 0) {
    return
  }
  tspPhotoForm.get('day')?.setValue(day.day)
  tspPhotoForm.get('uploadDate')?.setValue(date)
  emit('update:tspPhotoData', tspPhotoForm.getValue())
}

const photoUploadStatus = ref<TspPhotoTypes.ObtainStatusResult>({})

function computedStatus(day: number) {
  const count = photoUploadStatus.value[day]
  return count != null && count > 0 ? 'uploaded'
      : count != null && count === 0 ? 'unupload'
          : 'unknown'
}

function obtainStatus() {
  TspPhotoApi.obtainStatus(tspPhotoForm.getValue()).then(res => {
    photoUploadStatus.value = res.data
    computedCalendar()
  })
}

function computedCalendar() {
  const value: Date = tspPhotoForm.get('month')?.getValue() ?? new Date()
  const beginOfMonth = times.beginOfMonth(times.parse(value))
  const endOfMonth = times.endOfMonth(times.parse(value))

  const firstDayIndex = beginOfMonth.weekday - 1

  const yu_shu = (endOfMonth.day + firstDayIndex) % 7

  const count = yu_shu > 0 ? (7 - yu_shu) + (endOfMonth.day + firstDayIndex) : (endOfMonth.day + firstDayIndex)
  const days_: Array<Array<TspPhotoTypes.DayType | null>> = []

  let temp: Array<TspPhotoTypes.DayType | null> = []
  for (let i = 0; i < count; i++) {
    if (i < firstDayIndex) {
      temp.push(null)
    } else if (i >= firstDayIndex && i < firstDayIndex + endOfMonth.day) {
      const day = i - firstDayIndex + 1
      temp.push({
        year: beginOfMonth.year,
        month: beginOfMonth.month,
        day: day,
        status: computedStatus(day),
        photoCount: photoUploadStatus.value[day] ?? 0
      })

    } else {
      temp.push(null)
    }
    if (temp.length === 7) {
      days_.push(temp)
      temp = []
    }
  }
  days.value = days_
}

tspPhotoForm.get('tspId')?.watchValue(() => {
  obtainStatus()
  emit('update:tspPhotoData', tspPhotoForm.getValue())
})
tspPhotoForm.get('month')?.watchValue((month) => {
  if (month == null) {
    return
  }
  tspPhotoForm.get('day')?.setValue(1)
  tspPhotoForm.get('uploadDate')?.setValue(times.format(times.parse(month), FMT.month) + '-01')
  obtainStatus()
  emit('update:tspPhotoData', tspPhotoForm.getValue())
})

onMounted(() => {
  if (props.status === 'edit') {
    searchHandler()
        .then((data) => {
          if (data.length === 0) {
            return
          }
          selectedRowKeys.value = [ data[0].id ]
          tspPhotoForm.get('tspId')?.setValue(data[0].id)
          tspPhotoForm.get('pointName')?.setValue(data[0].pointName)
        })
  } else {
    tspPhotoForm.get('tspId')?.setValue(props.tspPhotoData.tspId)
    tspPhotoForm.get('pointName')?.setValue(props.tspPhotoData.pointName)
  }
})

defineExpose({
  refresh() {
    obtainStatus()
  }
})

</script>

<template>
  <div class="calendar-wrapper">
    <div class="calendar-title">
      <IxForm :control="tspPhotoForm" class="calendar-form" layout="inline">
        <IxFormItem>
          <IxInput v-if="status === 'view'" control="pointName" readonly/>

          <IxPopover v-if="status === 'edit'" v-model:visible="visible" closable header="小区列表" placement="bottom" trigger="click">
            <IxInput control="pointName" placeholder="请选择小区"/>
            <template #content>
              <IxTable v-model:selectedRowKeys="selectedRowKeys" :columns="columns" :dataSource="datasource" :pagination="pagination" :spin="tableSpin" get-key="id"/>
            </template>
          </IxPopover>
        </IxFormItem>
        <IxFormItem>
          <IxDatePicker :disabled-date="disabledDate" control="month" type="month" @change="computedCalendar"/>
        </IxFormItem>
      </IxForm>
    </div>
    <table class="calendar">
      <thead>
      <tr>
        <th v-for="item in weekday" :key="'weekday-' + item" class="weekday">{{ item }}</th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="(item, index) in days" :key="'day-' + index">
        <td v-for="(it, i) in item" :key="'day-' + i" :class="{blank:it == null}" class="day">
          <div v-if="it != null" :class="{'active-day': it.day === tspPhotoData.day && it.month === (tspPhotoData.month?.getMonth()??-1) + 1 && it.year === tspPhotoData.month?.getFullYear()}" class="day-content" @click="selectDayHandler(it)">
            <div class="day-number">
              <div>{{ it.day }}</div>
              <div>{{ it.day === new Date().getDate() && it.month === new Date().getMonth() + 1 && it.year === new Date().getFullYear() ? '今' : '' }}</div>
            </div>
            <IxTagGroup v-if="it.status === 'uploaded'" :gap="0" class="day-status">
              <IxTag status="success">已上传</IxTag>
              <IxTag status="success">{{ it.photoCount }}张</IxTag>
            </IxTagGroup>
            <IxTag v-else-if="it.status === 'unupload'" class="day-status" status="error">未上传</IxTag>
            <div v-else class="day-status"></div>
          </div>
        </td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<style lang="stylus" scoped>
.calendar-wrapper {
  flex 1
  padding 1rem
  box-sizing border-box
  border-right: 1px solid rgb(211, 215, 222);

  .calendar-form {
    width 100%
    height 4rem

    :deep(.ix-form-item):first-child {
      width 30%
    }

    :deep(.ix-form-item):nth-child(2) {
      width 10%
    }
  }

  .calendar {
    width 100%
    height calc(100% - 4rem);
    margin-top 1rem
    box-sizing border-box
    table-layout fixed

    border-collapse: collapse;
    border: 1px solid rgb(211, 215, 222);

    thead {
      height 4rem

      th {
        text-align center
      }
    }

    tbody {
      height calc(100% - 4rem);
    }

    .day {
      border-top: 1px solid rgb(211, 215, 222);

      &:not(.blank) {
        border: 1px solid rgb(211, 215, 222);
      }


      .day-content {
        cursor pointer

        height 100%
        width 100%
        display flex
        flex-direction column
        justify-content space-around
        padding 1rem

        &:hover {
          background-color: rgba(59, 130, 246, 0.1);
        }

        &.active-day {
          background-color: rgba(59, 130, 246, 0.1);
        }

        .day-number {
          font-size 3rem
          font-weight bold
          display: flex
          justify-content: space-between;

          & > div:last-child {
            color #165DFF
          }
        }

        .day-status {
          width 100%;
          height 20px;

          :deep(.ix-space-item) {
            flex 1

            & > span {
              width 100%
            }
          }
        }
      }
    }
  }

}

</style>
