import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:uuid/uuid.dart'; class House { final String id; final String title; final String? address; final double? latitude; final double? longitude; final double? totalPrice; final double? totalPing; final double? age; final String? propertyType; final String? summaryNotes; final double? overallRating; final bool isFavorite; final DateTime? createdAt; House({ required this.id, required this.title, this.address, this.latitude, this.longitude, this.totalPrice, this.totalPing, this.age, this.propertyType, this.summaryNotes, this.overallRating, this.isFavorite = false, this.createdAt, }); factory House.fromJson(Map json) { return House( id: json['id'] as String? ?? const Uuid().v4(), title: json['title'] as String? ?? '未命名物件', address: json['address'] as String?, latitude: double.tryParse(json['latitude']?.toString() ?? ''), longitude: double.tryParse(json['longitude']?.toString() ?? ''), totalPrice: double.tryParse(json['total_price']?.toString() ?? ''), totalPing: double.tryParse(json['total_ping']?.toString() ?? ''), age: double.tryParse(json['age']?.toString() ?? ''), propertyType: json['property_type'] as String?, summaryNotes: json['summary_notes'] as String?, overallRating: double.tryParse(json['overall_rating']?.toString() ?? '0'), isFavorite: json['is_favorite'] == 1 || json['is_favorite'] == true, createdAt: json['created_at'] != null ? DateTime.tryParse(json['created_at']) : null, ); } // UI Helper: 評分顏色 Color get ratingColor { if ((overallRating ?? 0) >= 4) return Colors.green; if ((overallRating ?? 0) >= 3) return Colors.orange; return Colors.red; } // 格式化顯示價格與坪數 String get priceTag => totalPrice != null ? '${totalPrice} 萬' : '價格未定'; String get infoSummary => '${propertyType ?? "未知"} | ${age ?? "?"}年 | ${totalPing ?? "?"}坪'; } // 檢查項目定義 (Template) class CheckItem { final String id; final String categoryId; final String name; final bool isDefault; CheckItem({required this.id, required this.categoryId, required this.name, this.isDefault = true}); factory CheckItem.fromJson(Map json) { return CheckItem( id: json['id'] as String, categoryId: json['category_id'] as String, name: json['name'] as String, isDefault: json['is_default'] == 1, ); } } // 新增照片模型 class HousePhoto { final String id; final String houseId; final String? evaluationId; // 關聯特定評估項目 final String filePath; final String? description; HousePhoto({required this.id, required this.houseId, this.evaluationId, required this.filePath, this.description}); factory HousePhoto.fromJson(Map json) { return HousePhoto( id: json['id'] as String, houseId: json['house_id'] as String, evaluationId: json['evaluation_id'] as String?, filePath: json['file_path'] as String, description: json['description'] as String?, ); } // 取得完整圖片網址 // String get fullUrl => "https://api.gex.com.tw/uploads/$filePath"; String get fullUrl { if (filePath.startsWith('http')) { return filePath; } return "https://api.gex.com.tw/uploads/$filePath"; } } // 新增評估紀錄模型 class HouseEvaluation { String? id; // 【修改】允許為 null (新建立的評估還沒有 ID) String houseId; // 移除 final String checkItemId; // 移除 final String itemName; // 移除 final,讓前端可以賦值 int score; // 【修改】移除 final,讓表單可以更新分數 String? itemMemo; // 【修改】移除 final,讓表單可以更新備註 HouseEvaluation({ this.id, // 【修改】移除 required required this.houseId, required this.checkItemId, required this.itemName, // 給予預設值,解決報錯 this.score = 0, this.itemMemo, }); factory HouseEvaluation.fromJson(Map json) { return HouseEvaluation( id: json['id'] as String?, houseId: json['house_id'] as String? ?? '', checkItemId: json['check_item_id'] as String? ?? '', itemName: json['itemName'] as String? ?? '', score: int.tryParse(json['score']?.toString() ?? '0') ?? 0, itemMemo: json['item_memo'] as String?, ); } } // Tag class Tag { final String id; final String name; final String colorHex; bool isSelected; // UI 用:判斷是否被選取 Tag({ required this.id, required this.name, required this.colorHex, this.isSelected = false, }); factory Tag.fromJson(Map json) { return Tag( id: json['id'] as String, name: json['name'] as String, colorHex: json['color_hex'] as String? ?? '#CCCCCC', ); } // 輔助:轉換 Hex String 為 Color 物件 Color get color { final hexCode = colorHex.replaceAll('#', ''); return Color(int.parse('FF$hexCode', radix: 16)); } } // 檢查項目大類模型 class CheckCategory { final String id; final String name; final int sortOrder; CheckCategory({required this.id, required this.name, required this.sortOrder}); factory CheckCategory.fromJson(Map json) { return CheckCategory( id: json['id'] as String, name: json['name'] as String, sortOrder: int.tryParse(json['sort_order']?.toString() ?? '0') ?? 0, ); } }