import { inject, Injectable, signal } from '@angular/core';
import { Subject } from 'rxjs';
import { getLevelColor } from '../app.util';
import { ApiService } from './api.service';
import { BasicDataService } from './basic.service';
import { SettingService } from './setting.service';

const mockLevels: Knowledge.RiskLevelDtoWithColor[] = [
  {
    id: 1,
    value: 'R1',
    description: '重大风险',
    color: '红色',
    responsible: '由集团级、公司级、部门/中心级、班组（车站）级4个层级按各自职责要求，落实具体管控措施',
    standard: '频繁的出现严重后果事件或发现存在隐患或有明显不满足的趋势，可定为红色风险条目',
  },
  {
    id: 2,
    value: 'R2',
    description: '较大风险',
    color: '橙色',
    responsible: '由公司级、部门/中心级、班组（车站）级3个层级按各自职责要求，落实具体管控措施',
    standard: '偶而的出现严重后果事件或发现存在隐患或有明显不满足的趋势，可定为橙色风险条目',
  },
  {
    id: 3,
    value: 'R2*',
    description: '特殊较大风险',
    color: '橙色',
    responsible: '由公司级、部门/中心级、班组（车站）级3个层级按各自职责要求，落实具体管控措施',
    standard: '偶而的出现严重后果事件或发现存在隐患或有明显不满足的趋势，可定为橙色风险条目',
  },
  {
    id: 4,
    value: 'R3',
    description: '一般风险',
    color: '黄色',
    responsible: '由部门/中心级、班组（车站）级2个层级按各自职责要求，落实具体管控措施',
    standard: '极少的出现严重后果事件或发现存在隐患或有明显不满足的趋势，可定为黄色风险条目',
  },
  {
    id: 5,
    value: 'R4',
    description: '低风险',
    color: '蓝色',
    responsible: '由班组（车站）级直接负责落实具体管控措施',
    standard: '基本没出现严重后果事件或发现存在隐患或有明显不满足的趋势，可定为蓝色风险条目',
  },
];

const mockCategories: Knowledge.RiskTypeDto[] = [
  // {
  //   id: 1,
  //   value: '客运组织',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory(['客流疏导', '车站环境', '乘客行为']),
  // },
  // {
  //   id: 2,
  //   value: '行车组织',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory(['调度指挥', '正常行车作业', '非正常行车作业', '车场调车作业', '应急行车处置']),
  // },
  // {
  //   id: 3,
  //   value: '施工检修',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory(['轨行区施工', '车场施工', '车站施工', '工程车开行']),
  // },
  // {
  //   id: 4,
  //   value: '车辆运维',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory([
  //     '车钩/车体/转向架/胶轮',
  //     '受电弓/集电靴/接地靴',
  //     '车门',
  //     '牵引/制动/控制',
  //     '蓄电池/辅助电源',
  //     '空调/广播/视频/照明等',
  //     '特种设备',
  //     'DCC管理',
  //     '工程车辆',
  //   ]),
  // },
  // {
  //   id: 5,
  //   value: '通号运维',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory([
  //     '列车自动防护系统',
  //     '列车自动运行系统',
  //     '列车自动监控系统',
  //     '联锁设备',
  //     '传输网络系统',
  //     '无线通信/专用电话设备',
  //     '转辙设备',
  //     '轨道占用检查设备',
  //     '电源设备',
  //   ]),
  // },
  // {
  //   id: 6,
  //   value: '工务运维',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory(['桥梁', '隧道', '轨道', '车站主体结构', '工程车辆']),
  // },
  // {
  //   id: 7,
  //   value: '供电运维',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory([
  //     '中高压设备',
  //     '牵引直流设备',
  //     '低压配电设备',
  //     '电力监控系统',
  //     '直流/应急电源设备',
  //     '电缆',
  //     '杂散电流防护',
  //     '柔性/刚性接触网',
  //     '接触轨/供电轨',
  //   ]),
  // },
  // {
  //   id: 8,
  //   value: '物资后勤',
  //   company: '',
  //   status: 0,
  //   isDelete: 0,
  //   categories: mapStringToCategory([
  //     '易燃品/危废品仓库',
  //     '道口及场内交通',
  //     '特种设备',
  //     '膳食',
  //     '储运',
  //     '膳食',
  //     '公共环境及卫生',
  //     '房屋及其附属设施',
  //   ]),
  // },
];

@Injectable({
  providedIn: 'root',
})
export class KnowledgeService {
  private setting = inject(SettingService);
  private basic = inject(BasicDataService);

  // levels
  private _levelUpdateDate = signal<string>(new Date().toISOString());
  levelUpdateDate = this._levelUpdateDate.asReadonly();
  private _levels = signal<Knowledge.RiskLevelDtoWithColor[]>(mockLevels);
  levels = this._levels.asReadonly();
  get levelsKeys() {
    return this._levels().map(item => item.value);
  }

  // types
  private _typeUpdateDate = signal<string>('');
  typeUpdateDate = this._typeUpdateDate.asReadonly();
  private _types = signal<Knowledge.RiskTypeDto[]>(mockCategories);
  types = this._types.asReadonly();
  get typesKeys() {
    return this._types().map(item => item.value);
  }
  onTypesChange = new Subject<void>();

  categories = signal<Knowledge.RiskCategoryDto[]>([]);

  private _docs = signal<Knowledge.Doc[]>([]);
  docs = this._docs.asReadonly();
  get docsKeys() {
    return this._docs().map(item => item.id);
  }

  private _riskItems = signal<Knowledge.RiskItem[]>([]);
  riskItems = this._riskItems.asReadonly();

  onRiskItemsChange = new Subject<void>();

  getCategoriesByType(type: number) {
    const typeDto = this.types().find(c => c.id === type);
    if (!typeDto) return [];
    return typeDto.categories;
  }

  getCategoryOptionsByType(type: number): Option<number>[] {
    const types = this.getCategoriesByType(type);
    return types.map(type => ({
      label: type.value,
      value: type.id,
    }));
  }

  getDepartmentOptionsByCategory(category: number) {
    const cateDto = this.categories().find(c => c.id === category);
    if (!cateDto) return [];
    return this.basic.departments.filter(d => cateDto.departments.includes(d.id));
  }

  getTypeName(typeId: number) {
    return this.types().find(t => t.id === typeId)?.value;
  }

  getCategoryName(categoryId: number, typeId: number) {
    return this.types()
      .find(t => t.id === typeId)
      ?.categories.find(c => c.id === categoryId)?.value;
  }

  getDocName(docId: number) {
    return this._docs().find(d => d.id === docId)?.name;
  }

  getDocDto(docId: number) {
    return this._docs().find(d => d.id === docId);
  }

  constructor(private readonly api: ApiService) {}
  async init() {
    // if (this.levelsKeys.length > 0 && this.typesKeys.length > 0) return Promise.resolve();
    return Promise.all([this.fetchRiskTypes(), this.fetchDocs(), this.fetchRiskItems()]);
  }

  async fetchRiskLevels() {
    this.api.knowledge.getRiskLevels().then(res => {
      this.updateLevels(res.data);
      this._levelUpdateDate.set(res.updateDate);
    });
  }

  async fetchRiskTypes() {
    this.api.knowledge.getRiskTypes().then(res => {
      this._types.set(res.list);
      this._typeUpdateDate.set(res.updateDate);
      this.categories.set([
        ...res.list.reduce((acc, t) => [...acc, ...t.categories], [] as Knowledge.RiskCategoryDto[]),
      ]);
      this.onTypesChange.next();
    });
  }

  async fetchDocs() {
    this.api.knowledge.getAllDoc(this.setting.userCompany).then(res => {
      this._docs.set(res);
    });
  }

  async fetchRiskItems() {
    this.api.knowledge.getAllItems().then(res => {
      this._riskItems.set(res);
      this.onRiskItemsChange.next();
    });
  }

  updateLevels(levels: Knowledge.RiskLevelDto[]) {
    this._levels.set(
      levels.map(l => {
        return {
          ...l,
          color: getLevelColor(l.value),
        };
      })
    );
  }
}
