<?php
// public/submit.php
declare(strict_types=1);

// Always start session for POST handlers
if (session_status() !== PHP_SESSION_ACTIVE) {
  session_start();
}

// Read flow early
$flow = $_POST['flow'] ?? '';

require __DIR__ . '/../includes/db.php';
require __DIR__ . '/../includes/helpers.php';

// -------- SAFE assignment resolver (no redirects, no require of require_assignment.php) --------
$assignment = [];
if ($flow === 'register') {
  // 1) try session (set during login)
  if (!empty($_SESSION['assignment']) && is_array($_SESSION['assignment'])) {
    $assignment = $_SESSION['assignment'];
  }

  // 2) fall back to hidden fields posted from index.php
  $assignment = array_merge([
    'state_name'    => $_POST['state_name']    ?? '',
    'state_code'    => $_POST['state_code']    ?? '',
    'nodal_name'    => $_POST['nodal_name']    ?? ($_POST['nodal_code'] ?? ''),
    'nodal_code'    => $_POST['nodal_code']    ?? '',
    'district_name' => $_POST['district_name'] ?? ($_POST['district_code'] ?? ''),
    'district_code' => $_POST['district_code'] ?? '',
    'ulb_name'      => $_POST['ulb_name']      ?? '',
    'ulb_code'      => $_POST['ulb_code']      ?? '',
  ], is_array($assignment) ? $assignment : []);

  if (empty($assignment['ulb_code'])) {
    // Don’t redirect—return JSON so frontend can show message
    json_response(['success'=>false,'message'=>'Assignment missing. Please reload the page and try again.']);
  }
}

function resolve_assignment_from_tree(string $stateKey, string $nodalKey, string $districtKey, string $ulbName): ?array {
  // up_admin_tree.php should be in the same folder as this file
  $TREE = include __DIR__ . '/up_admin_tree.php';

  if (empty($TREE[$stateKey])) return null;
  $state      = $TREE[$stateKey];
  $state_name = $state['name'] ?? $stateKey;
  $state_code = $state['code'] ?? '';

  $nodals = $state['nodals'] ?? [];
  if (empty($nodals[$nodalKey])) return null;
  $nodal      = $nodals[$nodalKey];
  $nodal_code = $nodal['code'] ?? '';

  $districts = $nodal['districts'] ?? [];
  if (empty($districts[$districtKey])) return null;
  $district      = $districts[$districtKey];
  $district_code = $district['code'] ?? '';

  $ulb_code = '';
  foreach ($district['ulbs'] ?? [] as $u) {
    if (isset($u['name']) && $u['name'] === $ulbName) {
      $ulb_code = $u['code'] ?? '';
      break;
    }
  }
  if ($ulb_code === '') return null;

  return [
    'state_name'    => $state_name,
    'state_code'    => $state_code,
    'nodal_name'    => $nodalKey,
    'nodal_code'    => $nodal_code,
    'district_name' => $districtKey,
    'district_code' => $district_code,
    'ulb_name'      => $ulbName,
    'ulb_code'      => $ulb_code,
  ];
}

/**
 * Common helpers
 */
function save_base64_photo(string $dataUri, string $prefix): array {
  if (!preg_match('/^data:image\/(png|jpeg|jpg);base64,/', $dataUri)) {
    return [false, 'Photo invalid', null];
  }
  $cfg = require __DIR__ . '/../includes/config.php';
  $upload_dir = $cfg['upload_dir'];
  if (!is_dir($upload_dir)) mkdir($upload_dir,0755,true);

  $type = (strpos($dataUri,'image/png')!==false) ? 'png' : 'jpg';
  $bin  = base64_decode(substr($dataUri, strpos($dataUri, ',')+1));
  $fname = $prefix . '_' . time() . '_' . bin2hex(random_bytes(6)) . '.' . $type;
  $fpath = $upload_dir . DIRECTORY_SEPARATOR . $fname;
  file_put_contents($fpath, $bin);

  $photo_url = rtrim($cfg['upload_base'], '/\\') . '/' . $fname;
  return [true, null, $photo_url];
}

/* ============================================================
   NEW: Executive Registration (one-time, no assignment needed)
   flow = register_executive
   ============================================================ */
if ($flow === 'register_executive') {
  // Fields
  $phone        = trim($_POST['phone'] ?? '');
  $fullName     = trim($_POST['full_name'] ?? '');
  $email        = trim($_POST['email'] ?? '');
  $address      = trim($_POST['address'] ?? '');
  $homeDistrict = trim($_POST['home_district'] ?? ''); // belongs (volunteer ka apna district)
  $dutyState    = trim($_POST['duty_state'] ?? '');
  $dutyNodal    = trim($_POST['duty_nodal'] ?? '');
  $dutyDistrict = trim($_POST['duty_district'] ?? '');
  $dutyUlb      = trim($_POST['duty_ulb'] ?? '');
  $password     = (string)($_POST['password'] ?? '');

  // Validations
  if (!preg_match('/^[0-9]{10}$/', $phone)) {
    json_response(['success'=>false,'message'=>'Phone must be exactly 10 digits (do not include +91).']);
  }
  if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    json_response(['success'=>false,'message'=>'Please enter a valid email address.']);
  }
  if (strlen($fullName) < 2) {
    json_response(['success'=>false,'message'=>'Please enter your full name.']);
  }
  if ($homeDistrict === '') {
    json_response(['success'=>false,'message'=>'Please enter your Home District (belongs).']);
  }
  if (strlen($password) < 6) {
    json_response(['success'=>false,'message'=>'Password must be at least 6 characters.']);
  }
  if ($dutyState === '' || $dutyNodal === '' || $dutyDistrict === '' || $dutyUlb === '') {
    json_response(['success'=>false,'message'=>'Please select complete Duty Assignment (State, Nodal, District, ULB).']);
  }

  try {
    // Uniqueness checks
    $stmt = $pdo->prepare('SELECT id, phone, email FROM executives WHERE phone = :p OR email = :e LIMIT 1');
    $stmt->execute(['p'=>$phone, 'e'=>$email]);
    $existing = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($existing) {
      if (!empty($existing['phone']) && $existing['phone'] === $phone) {
        json_response(['success'=>false,'message'=>'This phone number is already registered.']);
      }
      if (!empty($existing['email']) && $existing['email'] === $email) {
        json_response(['success'=>false,'message'=>'This email is already registered.']);
      }
    }

    // ⚠️ Store PLAIN password (DEV/TEST ONLY)
    $plain = $password;

    // Insert executive  (NOTE: column name is `password` after SQL rename)
    $ins = $pdo->prepare('INSERT INTO executives
      (phone, full_name, email, address, home_district, duty_state, duty_nodal, duty_district, duty_ulb, password, created_at)
      VALUES (:phone, :full_name, :email, :address, :home_district, :duty_state, :duty_nodal, :duty_district, :duty_ulb, :password, :created_at)');
    $ins->execute([
      'phone'         => $phone,
      'full_name'     => $fullName,
      'email'         => $email,
      'address'       => $address,
      'home_district' => $homeDistrict,
      'duty_state'    => $dutyState,
      'duty_nodal'    => $dutyNodal,
      'duty_district' => $dutyDistrict,
      'duty_ulb'      => $dutyUlb,
      'password'      => $plain,
      'created_at'    => date('Y-m-d H:i:s'),
    ]);
    $userId = (int)$pdo->lastInsertId();

    // Login + set assignment to DUTY mapping (names + codes) for index.php badge
    if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
    $_SESSION['user_id'] = $userId;

    $resolved = resolve_assignment_from_tree($dutyState, $dutyNodal, $dutyDistrict, $dutyUlb);
    if (!$resolved) {
      json_response(['success'=>false,'message'=>'Duty assignment not found in admin tree (state/nodal/district/ULB mismatch).']);
    }
    // store full structure
    $_SESSION['assignment'] = $resolved;

    // (optional) short keys for backward compatibility
    $_SESSION['assignment'] += [
      'state'    => $resolved['state_name'],
      'nodal'    => $resolved['nodal_name'],
      'district' => $resolved['district_name'],
      'ulb'      => $resolved['ulb_name'],
    ];

    json_response(['success'=>true,'message'=>'Registered successfully','redirect'=>'index.php']);
  } catch (Exception $e) {
    json_response(['success'=>false,'message'=>'DB error: '.$e->getMessage()]);
  }
}


/* ============================================================
   Existing: Household Registration flow (first visit)
   flow = register
   ============================================================ */
if ($flow === 'register') {
  // required inputs
  $date  = $_POST['date'] ?? '';
  $time  = $_POST['time'] ?? '';
  $ward  = trim($_POST['ward'] ?? '');
  $house = trim($_POST['house_no'] ?? '');
  $name  = trim($_POST['name'] ?? '');
  $phone = validate_phone($_POST['phone'] ?? '');
  $waste = $_POST['waste_segregation'] ?? '';
  $d2d   = $_POST['door_to_door'] ?? '';           // ✅ add
  $photo = $_POST['photo_data'] ?? '';

  // geo (raw) — from hidden fields populated by app.js
  $geo_lat      = $_POST['geo_lat'] ?? null;
  $geo_lng      = $_POST['geo_lng'] ?? null;
  $geo_addr     = trim($_POST['geo_addr'] ?? '');
  $geo_village  = trim($_POST['geo_village'] ?? '');
  $geo_district = trim($_POST['geo_district'] ?? '');
  $geo_state    = trim($_POST['geo_state'] ?? '');
  $geo_country  = trim($_POST['geo_country'] ?? '');
  $geo_cc       = strtoupper(trim($_POST['geo_cc'] ?? ''));
  $captured_at  = $_POST['captured_at'] ?? null;

  // validation
  $errors = [];
  if (!$date || !$time) $errors[]='Date/time required';
  if (!$ward) $errors[]='Ward required';
  if (!$house) $errors[]='House no required';
  if (!$name) $errors[]='Name required';
  if (!$phone) $errors[]='Phone invalid';
  if (!$waste) $errors[]='Waste segregation required';
  if (!$d2d)   $errors[]='Door to Door Collection required';   // ✅ add
  if (!$photo) $errors[]='Photo required';
  if ($errors) json_response(['success'=>false,'message'=>implode(', ', $errors)]);

  // enforce unique phone (global). If you want per-ULB uniqueness, add AND ulb_code=:ulb in the query
  $st = $pdo->prepare('SELECT id FROM residents WHERE phone=:p LIMIT 1');
  $st->execute(['p'=>$phone]);
  if ($st->fetch()) json_response(['success'=>false,'message'=>'Phone already registered']);

  // save photo
  [$ok, $perr, $photo_path] = save_base64_photo($photo, 'reg');
  if (!$ok) json_response(['success'=>false,'message'=>$perr ?? 'Photo invalid']);

  // timestamp
  $created_at = date('Y-m-d H:i:s', strtotime($date.' '.$time.':00'));

  // pull location codes from session assignment (set by registration/login)
  $state_code    = $assignment['state_code'];
  $nodal_code    = $assignment['nodal_code'];
  $district_code = $assignment['district_code'];
  $ulb_code      = $assignment['ulb_code'];

  // insert resident + training #1 (initial)
  $pdo->beginTransaction();
  try {
    // residents (now stores geo columns + assignment codes)
    $ins = $pdo->prepare('INSERT INTO residents
  (ward, house_no, name, phone, waste_segregation, door_to_door, photo_path,
   created_at, updated_at, trainings_completed,
   reg_lat, reg_lng, reg_address, reg_village, reg_district, reg_state,
   reg_country, reg_country_code, reg_captured_at,
   state_code, nodal_code, district_code, ulb_code)
  VALUES
  (:w,:h,:n,:p,:ws,:d2d,:ph,
   :c,:c,1,
   :lat,:lng,:addr,:village,:district,:state,
   :country,:cc,:captured,
   :stc,:noc,:dic,:ulc)');
$ins->execute([
  'w'=>$ward,
  'h'=>$house,
  'n'=>$name,
  'p'=>$phone,
  'ws'=>$waste,
  'd2d'=>$d2d,          // << binding
  'ph'=>$photo_path,
  'c'=>$created_at,
  'lat'=>($geo_lat !== null && $geo_lat !== '') ? $geo_lat : null,
  'lng'=>($geo_lng !== null && $geo_lng !== '') ? $geo_lng : null,
  'addr'=>$geo_addr ?: null,
  'village'=>$geo_village ?: null,
  'district'=>$geo_district ?: null,
  'state'=>$geo_state ?: null,
  'country'=>$geo_country ?: null,
  'cc'=>$geo_cc ?: null,
  'captured'=>$captured_at ?: null,
  // assignment codes
  'stc'=>$state_code,
  'noc'=>$nodal_code,
  'dic'=>$district_code,
  'ulc'=>$ulb_code,
]);

    $resident_id = (int)$pdo->lastInsertId();

    // trainings #1 (store same geo snapshot too)
    $insT = $pdo->prepare('INSERT INTO trainings
  (resident_id, training_number, waste_segregation, door_to_door, photo_path,
   training_date, created_at,
   lat, lng, address, village, district, state, country, country_code, captured_at, created_by_executive_id)
  VALUES
  (:rid,1,:ws,:d2d,:ph,:td,:now,
   :lat,:lng,:addr,:village,:district,:state,:country,:cc,:captured, :eid)');
$insT->execute([
  'rid'=>$resident_id,
  'ws'=>$waste,
  'd2d'=>$d2d,          // << binding
  'ph'=>$photo_path,
  'td'=>$created_at,
  'now'=>now(),
  'lat'=>($geo_lat !== null && $geo_lat !== '') ? $geo_lat : null,
  'lng'=>($geo_lng !== null && $geo_lng !== '') ? $geo_lng : null,
  'addr'=>$geo_addr ?: null,
  'village'=>$geo_village ?: null,
  'district'=>$geo_district ?: null,
  'state'=>$geo_state ?: null,
  'country'=>$geo_country ?: null,
  'cc'=>$geo_cc ?: null,
  'captured'=>$captured_at ?: null,
  'eid'=>$_SESSION['user_id'] ?? null,
]);

    $pdo->commit();
    json_response(['success'=>true,'message'=>'Registration saved (Training First recorded).']);
  } catch (Exception $e) {
    $pdo->rollBack();
    json_response(['success'=>false,'message'=>'DB error: '.$e->getMessage()]);
  }
}

/* ============================================================
   Existing: Officer adds Training #2 / #3
   flow = officer
   ============================================================ */
if ($flow === 'officer') {
  $resident_id = (int)($_POST['resident_id'] ?? 0);
  $waste = $_POST['waste_segregation'] ?? '';
  $d2d   = $_POST['door_to_door'] ?? '';             // ✅ add
  $date  = $_POST['date'] ?? '';
  $time  = $_POST['time'] ?? '';
  $photo = $_POST['photo_data'] ?? '';

  // geo from either _off or generic names
  $geo_lat      = $_POST['geo_lat_off'] ?? $_POST['geo_lat'] ?? null;
  $geo_lng      = $_POST['geo_lng_off'] ?? $_POST['geo_lng'] ?? null;
  $geo_addr     = trim($_POST['geo_addr_off'] ?? $_POST['geo_addr'] ?? '');
  $geo_village  = trim($_POST['geo_village_off'] ?? $_POST['geo_village'] ?? '');
  $geo_district = trim($_POST['geo_district_off'] ?? $_POST['geo_district'] ?? '');
  $geo_state    = trim($_POST['geo_state_off'] ?? $_POST['geo_state'] ?? '');
  $geo_country  = trim($_POST['geo_country_off'] ?? $_POST['geo_country'] ?? '');
  $geo_cc       = strtoupper(trim($_POST['geo_cc_off'] ?? $_POST['geo_cc'] ?? ''));
  $captured_at  = $_POST['captured_at_off'] ?? $_POST['captured_at'] ?? null;

  $errors = [];
  if (!$resident_id) $errors[]='Resident missing';
  if (!$waste) $errors[]='Waste segregation required';
  if (!$d2d)   $errors[]='Door to Door Collection required';  // ✅ add
  if (!$date || !$time) $errors[]='Date/time required';
  if (!$photo) $errors[]='Photo required';
  if ($errors) json_response(['success'=>false,'message'=>implode(', ', $errors)]);

  // verify resident + trainings_completed
  $st = $pdo->prepare('SELECT id, trainings_completed FROM residents WHERE id=:id LIMIT 1');
  $st->execute(['id'=>$resident_id]);
  $res = $st->fetch();
  if (!$res) json_response(['success'=>false,'message'=>'Resident not found']);

  $trainings_done = (int)$res['trainings_completed']; // after registration this is 1
  if ($trainings_done >= 3) json_response(['success'=>false,'message'=>'All trainings completed']);
  $next_num = $trainings_done + 1;  // 2 then 3

  // save photo
  [$ok, $perr, $photo_path] = save_base64_photo($photo, 't'.$next_num.'_'.$resident_id);
  if (!$ok) json_response(['success'=>false,'message'=>$perr ?? 'Photo invalid']);

  $training_dt = date('Y-m-d H:i:s', strtotime($date.' '.$time.':00'));

  $pdo->beginTransaction();
  try {
    // insert next training with geo
    $insT = $pdo->prepare('INSERT INTO trainings
  (resident_id, training_number, waste_segregation, door_to_door, photo_path,
   training_date, created_at,
   lat, lng, address, village, district, state, country, country_code, captured_at, created_by_executive_id)
  VALUES
  (:rid,:tn,:ws,:d2d,:ph,:td,:now,
   :lat,:lng,:addr,:village,:district,:state,:country,:cc,:captured, :eid)');

    $insT->execute([
      'rid'=>$resident_id,
      'tn'=>$next_num,
      'ws'=>$waste,
      'd2d'=>$d2d, 
      'ph'=>$photo_path,
      'td'=>$training_dt,
      'now'=>now(),
      'lat'=>($geo_lat !== null && $geo_lat !== '') ? $geo_lat : null,
      'lng'=>($geo_lng !== null && $geo_lng !== '') ? $geo_lng : null,
      'addr'=>$geo_addr ?: null,
      'village'=>$geo_village ?: null,
      'district'=>$geo_district ?: null,
      'state'=>$geo_state ?: null,
      'country'=>$geo_country ?: null,
      'cc'=>$geo_cc ?: null,
      'captured'=>$captured_at ?: null,
      'eid'=>$_SESSION['user_id'] ?? null,
    ]);

    // increment trainings_completed and update latest status
    $upd = $pdo->prepare('UPDATE residents
      SET trainings_completed = trainings_completed + 1,
          waste_segregation = :ws,
          door_to_door = :d2d,
          updated_at = :u
      WHERE id = :id');
    $upd->execute([
      'ws' => $waste,
      'd2d' => $d2d,
      'u'  => now(),
      'id' => $resident_id
    ]);

    $pdo->commit();
    json_response(['success'=>true,'message'=>'Training saved successfully']);
  } catch (Exception $e) {
    $pdo->rollBack();
    json_response(['success'=>false,'message'=>'DB error: '.$e->getMessage()]);
  }
}

json_response(['success'=>false,'message'=>'Invalid flow']);
